python3の日記

Python3を図書とともに勉強していくブログ

【初めてのPython(第7章)】文字列

f:id:pokita:20180426195830j:plain

文字列オブジェクトとは、シーケンスを持ちimmutable(不変)という特徴がある。

 

エスケープシーケンスとは

7.1.2

エスケープシーケンスとは、画面上に文字を出力する際に、文字そのものを出力するのではなく、文字色の変更やカーソルの移動、文字の消去など、文字出力の制御を行う特殊な文字列(生のバイトコード)のことである。直接生のバイトコードをプログラムの原文に打ち込むって話。

そのため、文字列の中に"\"が入った際は、「/以降はバイトコードが続くんだな」と思った方がいい。(\はWindows上では¥とも表記されるため、\=¥で読み進めてください。)

これが覚えるのを含めけっこうややっこしい。この章の鬼門だと思ってる。

 

エスケープシーケンス一覧

文字 説明
¥'  シングルコーテーション
¥" ダブルコーテーション 
¥t タブ
¥¥ バックスラッシュ
¥n 改行 (LF)
¥r 復帰 (CR)
¥0 Null文字
¥f 改ページ
¥ooo oooにはASCII文字の8進数3桁のコードが入ります
→ASCII文字が表示されます
¥xhh hhにはASCII文字の16進数2桁のコードが入ります
→ASCII文字が表示されます
¥uxxxx xxxxにはUnicodeの16進数4桁のコードが入ります
Unicodeの文字が表示されます

また文字リテラルについても、それぞれに対応した数値で表すことができる。"x"は120、"3"は51といった具合に。上の"oooにはASCII文字の8進数3桁のコードが入ります"はその対応した数値のことを言っている。

詳しい対応表は下。

 

 ASCII文字コード
文字 10進 8進 16進 文字 10進 8進 16進 文字 10進 8進 16進 文字 10進 8数 16進
(nul) 0 0000 0x00 (sp) 32 0040 0x20 @ 64 0100 0x40 ` 96 0140 0x60
(soh) 1 0001 0x01 ! 33 0041 0x21 A 65 0101 0x41 a 97 0141 0x61
(stx) 2 0002 0x02 " 34 0042 0x22 B 66 0102 0x42 b 98 0142 0x62
(etx) 3 0003 0x03 # 35 0043 0x23 C 67 0103 0x43 c 99 0143 0x63
(eot) 4 0004 0x04 $ 36 0044 0x24 D 68 0104 0x44 d 100 0144 0x64
(enq) 5 0005 0x05 % 37 0045 0x25 E 69 0105 0x45 e 101 0145 0x65
(ack) 6 0006 0x06 & 38 0046 0x26 F 70 0106 0x46 f 102 0146 0x66
(bel) 7 0007 0x07 ' 39 0047 0x27 G 71 0107 0x47 g 103 0147 0x67
(bs) 8 0010 0x08 ( 40 0050 0x28 H 72 0110 0x48 h 104 0150 0x68
(ht) 9 0011 0x09 ) 41 0051 0x29 I 73 0111 0x49 i 105 0151 0x69
(nl) 10 0012 0x0a * 42 0052 0x2a J 74 0112 0x4a j 106 0152 0x6a
(vt) 11 0013 0x0b + 43 0053 0x2b K 75 0113 0x4b k 107 0153 0x6b
(np) 12 0014 0x0c , 44 0054 0x2c L 76 0114 0x4c l 108 0154 0x6c
(cr) 13 0015 0x0d - 45 0055 0x2d M 77 0115 0x4d m 109 0155 0x6d
(so) 14 0016 0x0e . 46 0056 0x2e N 78 0116 0x4e n 110 0156 0x6e
(si) 15 0017 0x0f / 47 0057 0x2f O 79 0117 0x4f o 111 0157 0x6f
(dle) 16 0020 0x10 0 48 0060 0x30 P 80 0120 0x50 p 112 0160 0x70
(dc1) 17 0021 0x11 1 49 0061 0x31 Q 81 0121 0x51 q 113 0161 0x71
(dc2) 18 0022 0x12 2 50 0062 0x32 R 82 0122 0x52 r 114 0162 0x72
(dc3) 19 0023 0x13 3 51 0063 0x33 S 83 0123 0x53 s 115 0163 0x73
(dc4) 20 0024 0x14 4 52 0064 0x34 T 84 0124 0x54 t 116 0164 0x74
(nak) 21 0025 0x15 5 53 0065 0x35 U 85 0125 0x55 u 117 0165 0x75
(syn) 22 0026 0x16 6 54 0066 0x36 V 86 0126 0x56 v 118 0166 0x76
(etb) 23 0027 0x17 7 55 0067 0x37 W 87 0127 0x57 w 119 0167 0x77
(can) 24 0030 0x18 8 56 0070 0x38 X 88 0130 0x58 x 120 0170 0x78
(em) 25 0031 0x19 9 57 0071 0x39 Y 89 0131 0x59 y 121 0171 0x79
(sub) 26 0032 0x1a : 58 0072 0x3a Z 90 0132 0x5a z 122 0172 0x7a
(esc) 27 0033 0x1b ; 59 0073 0x3b [' 91 0133 0x5b { 123 0173 0x7b
(fs) 28 0034 0x1c < 60 0074 0x3c \ 92 0134 0x5c | 124 0174 0x7c
(gs) 29 0035 0x1d = 61 0075 0x3d ] 93 0135 0x5d } 125 0175 0x7d
(rs) 30 0036 0x1e > 62 0076 0x3e ^ 94 0136 0x5e ~ 126 0176 0x7e
(us) 31 0037 0x1f ? 63 0077 0x3f _ 95 0137 0x5f (del) 127 0177 0x7f
 
s = "a\x00b\x00c"
print(s)
>>>abc #x00は無を表す
print(len(s))
>>>5 #x00は一つのバイトコード
s ="\071\072\x66"
print(s)
>>>9:f

 

7.1.2

文字列を作る際、¥が含まれているとそれ以下の文字はエスケープシーケンスとして捉えられてしまい、純粋に文字列として"¥”を使いたいときなどに不便が生じる。(¥¥と書けばいいものの、面倒くさい。)

そんなときに便利なのがraw文字列使い方は簡単、””の前にrを置けばいいだけ!

s =r"\071\072\x66"
print(s)
>>>\071\072\x66

くそ便利。

 

7.1.5

Unicodeの話。ふむふむとUnicode文字列の特徴について読んでいたらここでも一言。「なおPython3ではstr型はデフォルトでUnicode型となる。」つまりただのstr型のこと。なんだ。

上記のASCII型だと177種類の文字までにしか対応できず、それではローマ字対応でいっぱいいっぱいで、日本語の出力なんて夢のまた夢。それを可能にしたのがUnicode型。

 

7.2.3

文字列で表記された数値をどうやって数値に変換するかという話。"1101"という2進法で表記された文字列を10進法で表記する場合。

s =int("1101")

 で一発目に数値変換してもいいのだけど、文字リテラルの特徴であるシーケンスを利用して、左にあるものから順に2の2乗を掛けていく方法を取る。

B = "1101"
K = len(B)
I = 0
while K:
I = I + int(B[0])*2**(k-1)
 #int(B[0])で文字列の先頭を数値化、*2**(k-1) で桁数-1の2乗を×
B =B[1:]
 #B = B[1:]で次の桁に移る
K = len(B)
 #K = len(B)で次の桁の桁数を取得。
print(I)
>>>13

ぼくにはこの方法しか思い浮かばなかったけど、本書では別の方法。

B = "1101"
I = 0
while B:
I = I * 2 +(ord(B[0]) - ord("0"))
B = B[1:]
print(I)
>>>13

文字列をord関数で数値化し、それとord(0)との差で数値化を完成させるとかいうテクニカルな変換方法。すごい。

 

文字列フォーマット

7.3

文字列フォーマットとは、文字列に様々な値の型を代入する、という操作のこと。変数の値を文字列に入れ込むのは結構大変。

例えば、I am 変数 and I am 変数 years old.という文字列を出力したい場合。

x = "name"
y = "age"
print("I am " + x + " and I am " + y + " years old.")
>>>I am name and I am age years old.

これはまだ代入する変数が文字列だから問題ないが、これがもし数値だったりタプルだったらどうだろう。

x = "Bob",
y = 27
print("I am " + x + " and I am " + y + " years old.")
>>>TypeError: must be str, not int

受け付けられないのである。だって、演算子”+”には数値と文字列を合わせるという機能は定義されていないから。この問題を解決するには、文字列に組み込みたい変数を全てstr関数で文字列化させるという手もあるけど…面倒くさい。

 

そういうときに登場するのが文字列フォーマット。本書では、文字列のために用意された%演算子を使用したフォーマットの話なんだけど、これも例に漏れずPython3以前の話……。Python3ではformatメソッドというのが文字列には用意されていて、それが%演算子の役割を代替している。

%演算子を仕様したフォーマットは今後廃止する可能性があると予告されている……。特に理由がない限り、文字列のフォーマットにはformat メソッドを使用したほうがよい。

 

formatメソッドについては、このサイトがオススメ。

uxmilk.jp

まとめるとこんな感じ。

name =["Bob","Tom","Sam","Spam"]
age = {"a":10,"b":20,"c":30}
s = "I am {0[2]} and I am {1[a]} years old.".format(name,age))
print(s)
>>>I am Sam and I am 10 years old.

 リストやディクショナリの値も数列に持ってこれる便利なメソッド。

 

 7.4

 文字列メソッドの話はまた今度。