0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonの文法の驚き

0
Posted at

(私の)背景

ふだん、趣味のコードはSchemeで書いている。学生時代は、CとC++で書いていた。
そんな育ち方をすると、Pythonの文法は驚きに満ちている。そんな私の驚きを共有したい。系統的な説明にはなっていないので、あくまで読み物として楽しんでほしい。

Pythonのデータ型

先週の記事も、ぜひ読んでいただきたい。

strの要素はstr

以下のテストコードを見てほしい。

types.py
#!/usr/bin/python3
str_cat="CAT"
print(f"name:str_cat, type:{type(str_cat)}, value:{str_cat}")
# name:str_cat, type:<class 'str'>, value:CAT

char_A=str_cat[1]
print(f"name:char_A, type:{type(char_A)}, value:{char_A}")
# name:char_A, type:<class 'str'>, value:A

Cの感覚だと、文字列(string)str_catの要素を、indexで指定してとってきたら当然文字(char)'A'が手に入ると思いきや、文字列(string)"A"が手に入ってしまう。

なぜなら、Pythonにはchar型はないから。indexで指定すると「1文字の文字列」が手に入る。

付随して以下が起きる。

  • シングルクォートでくくった'a'とダブルクォートでくくった"a"はまったく同じ。どちらも長さ1の文字列。
  • ord()みたいな、文字1文字をとる関数に2文字以上の文字列を突っ込むと、実行時にTypeErrorが起こる(実行前の型チェックは通る)。

bytes型

bytes型はtuple型(1,2,3)でも、list型[1,2,3]でもない。
バイナリのデータがぎっしり詰まったもの。

list型ではないけど、同じ書式のindex指定で要素を取り出すことができる。取り出した要素は0~255の範囲の整数(int)。

bytesは、要素を列挙する形では作れない。listやb'文字列'を、bytes()に食わせると、bytes型の変数になる。つまり、bytes()はコンストラクタ。

b_l=bytes([1, 2, 3]) # listから作る
b_t=bytes((1, 2, 3)) # tupleから作る
b_s=b'abc' # 直接作る

bytesは、(Schemeの)mapができる

リスト内包表記 (List Comprehension)と呼ばれる文法がある。

bytes([b ^ 0xff for b in data]) 

は、

(map (lambda (b) (logxor b #xff)) data)

に相当する。loopで回りながら、bytes型のbから1byteずつ取り出して処理して、リストを作り、最後にbytes()でくるんでbytes型に戻している。

上の例では、引数が1つだけだけど、複数の引数をとりたいなら、次のように書く。zipでくるんで引数たちを渡してやればよい。

flag = bytes([x ^ y ^ z for x, y, z in zip(b_favorite, b_enc_favorite, b_enc_flag)])

bytes型のNOT(ビット反転)の取り方

bytesは直接ビット反転できない。~演算子は整数に対してのみ定義されているため。そのため、bytesでビット反転したいときは、0xFFとXORする。発想の転換。

data = b'\x01\x02\xff'
not_data = bytes([b ^ 0xff for b in data])

メソッドと関数

Pythonには、メソッドも関数もある。型に紐づく操作はメソッドになりがち。型によらない操作は関数の形になりがち。

bytes.fromhex()

strb_fox="464f58"
b2_fox=bytes.fromhex(strb_fox)

bytes.fromhex()は、文字列を2文字ずつ取って16進数と解釈してbytesを作る関数。
普通、メソッドは変数xにたいしてx.encode()の形で呼ばれるが、これは、bytesが頭についている。「代替コンストラクタ (Alternative Constructors)」と呼ばれるもので、bytesのコンストラクタの仲間扱い(アウトプットがbytes)なので、bytesが苗字としてついている。

結びに

世界にはたくさんの言語がある。だけど、Pythonにも、Schemeのmapに相当する概念があったり、言語は親戚でもある。比較文化論的に楽しみながら、Pythonとも仲良くなれたらいいと思う。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?