内包表記いろいろ
この記事は Python Tips Advent Calendar 2012 9日目の記事です。
まず、list, set, dict は、それらを生成するための専用の構文を持っています。
>>> [1,2,3] # リスト生成 [1, 2, 3] >>> {1,2,3} # 集合生成 set([1, 2, 3]) >>> {1:1,2:2,3:3} # 辞書生成 {1: 1, 2: 2, 3: 3}
この構文を拡張した形で list, set, dict の内包表記が書けます。
>>> xs = [1,2,3] >>> [x for x in xs] # リスト内包表記 [1, 2, 3] >>> {x for x in xs} # 集合内包表記 set([1, 2, 3]) >>> {x:x for x in xs} # 辞書内包表記 {1: 1, 2: 2, 3: 3}
ただし、タプルだけは注意です。
>>> (1,2,3) # タプル生成 (1, 2, 3) >>> (x for x in xs) # ジェネレータ式 #doctest: +ELLIPSIS <generator object <genexpr> at 0x...>
タプルの形式で内包表記を行うと、ジェネレータ式として扱われます。
タプルを内包表記で作りたいなら、
>>> tuple(x for x in xs) # タプル作るならこうする (1, 2, 3)
このように書くのがいいでしょう。
また、内包表記はネストさせることができます。
>>> [(i,j) for i in range(3) for j in range(i)] [(1, 0), (2, 0), (2, 1)]
これは以下のように書くのと大体同じです。
>>> for i in range(3): ... for j in range(i): ... print (i,j) (1, 0) (2, 0) (2, 1)
当然これらは set や dict、ジェネレータでも使えます。
>>> {(i,j) for i in range(3) for j in range(i)} set([(2, 0), (1, 0), (2, 1)]) >>> {i:j for i in range(3) for j in range(i)} {1: 0, 2: 1} >>> list((i,j) for i in range(3) for j in range(i)) [(1, 0), (2, 0), (2, 1)]
もちろん if と組み合わせることもできます。
>>> [(i, j) for i in range(5) if i%2 == 0 for j in range(i) if j%2 == 0] [(2, 0), (4, 0), (4, 2)]
うまく活用していきましょう。そしてどこで改行するか悩みましょう。
.