銀月の符号

Python 使い見習いの日記・雑記

複雑なリスト内包表記の読み方

http://d.hatena.ne.jp/mssh/20080308#1204974183 を読んでリスト内包表記に苦戦していた頃を思い出したので。for 文 if 文がたくさん入って1行に書かれたリスト内包表記。ただの for 文、 if 文となにも変わらないことに気づいてからスムーズに読めるようになりました。 for 文 if 文は読めるけどリスト内包表記はちょっと、という人(とかつての自分)のために、リスト内包表記を直す方法書いてみます。

例に用いるのは同じく足して 5 になる組み合わせで。

ただの for 文 if 文に直すには、まず空リストを用意。最初の for の前を取り払って最後に append メソッドの呼び出しを加えます。引数にさきほど取り払ったものをいれます。あとインデントをしっかりつけて、コロンもつける。これで完了です。

>>> [(x, y) for x in range(10) for y in range(10) if x + y == 5 if x > y]
[(3, 2), (4, 1), (5, 0)]
>>>
>>> [(x, y)
... for x in range(10)
... for y in range(10)
... if x + y == 5
... if x > y]
[(3, 2), (4, 1), (5, 0)]
>>>
>>> temp = []
>>> for x in range(10):
...   for y in range(10):
...     if x + y == 5:
...       if x > y:
...         temp.append((x, y))
...
>>> temp
[(3, 2), (4, 1), (5, 0)]

for 文, if 文が入り乱れても大丈夫。最初の値を偶数のみにしてみるとこんな感じです。

>>> [(x, y)
... for x in range(10)
... if not x % 2
... for y in range(10)
... if x + y == 5
... if x > y]
[(4, 1)]
>>>
>>> temp = []
>>> for x in range(10):
...   if not x % 2:
...     for y in range(10):
...       if x + y == 5:
...         if x > y:
...           temp.append((x, y))
...
>>> temp
[(4, 1)]

ジェネレータ式も同じ書き方なので慣れておくと一石二鳥でお得、かもしれません。

>>> g = (
... (x, y)
... for x in range(10)
... for y in  range(10)
... if x + y == 5
... if x > y)
>>> for t in g:
...   print t
...
(3, 2)
(4, 1)
(5, 0)