Python リスト内包表記とジェネレータ
どちらもリストを生成するものだが、使いどころが違うので軽くまとめる。
リスト内包表記
よくあるmap的なメソッドの書き方の一つ。Pythonにもmapメソッドはあるがリスト内包表記のほうが高速なのでこっちを使おう。
リスト内包表記とmap
リスト内包表記
names = ['Alice', 'Bob', 'Carl', 'Dave']
[name[0] for name in names] # => ['A', 'B', 'C', 'D']
mapメソッド
names = ['Alice', 'Bob', 'Carl', 'Dave']
map(lambda name: name[0], names) # => ['A', 'B', 'C', 'D']
if リスト内包表記
リストから条件に当てはまる要素のリストを新たに作りたいとき使える。
if を続けることで複数の条件を書くことも可能だし、もちろんandでも書ける。
names = ['Alice', 'Bob', 'Carl', 'Dave']
[name for name in names if len(name) == 4] # => ['Carl', 'Dave']
[name for name in names if not len(name) == 4] # => ['Alice', 'Bob']
[name for name in words if not len(name) == 4 if len(name) < 5] # => ['Bob']
[name for name in words if not len(name) == 4 and len(name) < 5] # => ['Bob']
複数変数
zipを使うことで同時に複数リストから新たなリストを作ることができる。
namesA = ['Alice', 'Bob', 'Carl', 'Dave']
namesB = ['Peter', 'Micheal', 'John', 'Harry']
[" ".join([x, y]) for x, y in zip(namesA, namesB)]
# => ['Alice Peter', 'Bob Micheal', 'Carl John', 'Dave Harry']
forを重ねることで多重ループを表現できる。
namesA = ['Alice', 'Bob', 'Carl', 'Dave']
namesB = ['Peter', 'Micheal', 'John', 'Harry']
[" ".join([x, y]) for x in namesA for y in namesB]
# => ['Alice Peter',
# 'Alice Micheal',
# 'Alice John',
# 'Bob Peter',
# 'Bob Micheal',
# 'Bob John',
# 'Carl Peter',
# 'Carl Micheal',
# 'Carl John',
# 'Dave Peter',
# 'Dave Micheal',
# 'Dave John']
ジェネレータ
ジェネレータは定義された式から要素を生成する事ができる。
nextでジェネレータから値を取り出す事ができる。
g = (x ** 2 for x in range(5))
next(g) # => 0
next(g) # => 1
next(g) # => 4
next(g) # => 16
next(g) # StopIteration
ジェネレータを使うことで条件に合致したところで値を生成するのをストップしたりできる。ほかにも使いドコロはありますが。
おまけ itertools
Pythonのモジュールにitertoolsというものがあって、これはいい感じにイテレータを生成するメソッドが実装されている。
たとえば組み合わせを列挙したいとき
import itertools
itertools.combinations('ABCD', 2) # => (A,B) (A,C) (A,D) (B,C) (B,D) (C,D)
これはあくまでイテレータを生成するのであってlistを生成するわけではないので注意。
このようなちょっとした記法とかを問題を解きながら学べるのがこれ。
Udacity Design of computer programming
pythonで機械学習をしている(しようとしている)ブログ
努力1mmブログ