広告
2022/06/13

Python 内包表記の使い方をマスターする

タグ:python

内包表記とは何か

Pythonに置ける内包表記(comprehension)とはリストを簡単に作成・成形するための 機能だ。 リストをつくるときにはfor分が必要になりがちである:
    l = []
    for x in range(10):
      l.append(x ** 2)
  
しかしこれは"x^2を列挙したリスト"という単純な概念に対し3行ものコードを書いていて、 冗長である。
なんとか1行で済ませようと思うと、こうやる人もいるかもしれない:
    l = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
  
これはこれで賢いやり方だが、リストが長いときはあらかじめ計算しておく のが大変である。 これらの良いとこどりをしようとすると「リストを初期化するときに[]内にfor分のようなものを 簡潔に入れられないかな……」という考えに行きつく。
これが内包表記である。 内包表記のネーミングは関連する数学概念「集合の内包的記法」(集合の列挙を明示的に書き下す代わりに 要素が満たす条件を書く集合の定義方法) から取られている。

内包表記の使い方

内包表記の一般形は["ほしい値" for "要素" in "もとリスト"] である。 ここで"ほしい値"とはリストに入れたい値、例えば上の例では"x ** 2" である。ここでもとリストの要素を参照できるように"要素"にて 要素を何と呼ぶか、変数名を定義していると考えればよい。 とはいえ"ほしい値"の中で"要素"が必要ないケースもある。 例えば値が定数であるようなリストが欲しいなら
    l = [0 for _ in range(5)]
    print(l)
    [0, 0, 0, 0, 0]
  
のように使わない要素に"_"なる名前を割り当てておくことが慣例だ。

Ifとの組み合わせ

上記のベーシックなやり方だと、もとリストと同じ長さのリストしかつくれない。 条件式で入れる要素を選別することもできる。
    l = [i for i in range(10) if i % 2 == 1]
    print(l)
    [1, 3, 5, 7, 9]
  


内包表記での辞書の作り方

辞書型 (dict) にも内包表記ベースの作り方がある。
この場合は{[キー]: [バリュー] for [要素] in [リストなど]} のように書けばよい。
    d = {i: i + 1 for i in range(10)}
    print(d)
    {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}
  


応用例

アルファベットを列挙
    chars = [chr(i + ord('a')) for i in range(26)]
    print(chars)
  

FizzBuzzをする例 printのような副作用(標準出力にメッセージを出すなど)のある関数を 入れることもできる。ややイレギュラーな使い方ではあるが。
    [print("FizzBuzz" if i % 15 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else i ) for i in range(100)]