内包表記とジェネレーター式について

pythonで以下は書かれる。また参考として「Pythonによるあたらしいデータ分析の教科書」のP30を参考にした。
内包表記
リスト内包表記をみる。まず普通に[0,1,2]のリストを作ってみる。

a=[]
for i in range(3):
  a.append(i)
print(a)   #[0,1,2]

のようにappendを使うことになるが、リスト内包表記では1行でかける。

l=[i for i in range(3)]
print(l)  #[0,1,2]

これをリスト内包表記といい、この2つのプログラムは同じ意味を表している。
またセット内包表記というものもありこれは[]を{}にすれば良い。


次に辞書内包表記を見てみよう。2つ例を書く。1つめは

strs=["a","bc","def"]
print([str:len(str) for str in strs])  #{'a': 1, 'bc': 2, 'def': 3}

でこれはstrsの要素とその長さを辞書型で出力した例である。
2つ目の例はzipを使ったもので

s=["a","b","c"]
a=[0,1,2]
print({n:m for n,m in zip(s,a)})  #{'a': 0, 'b': 1, 'c': 2}

とかける。リストs,aの各要素に対応した辞書が作られる。


またfor文のあとにif文を追加することで特定の条件を満たす値をリストに入れることができる。

print([i*i for i in range(10) if i%3==0])   #0から10までで3で割り切れるもの。


また2次元のリストは次のようになる。

print([[(x,y) for x in range(3)]for y in range(4)])     #xが0,1,2でyが0,1,2,3の3*4行列になる


ジェネレーター式
ジェネレーター式はリスト内包表記の[]を()にしたものである。メリットとして値を1つずつ返すので多量のデータを処理するときにメモリをたくさん食わずにすむ。では詳しく例を上げてみてみる。
まずリストの場合は

l=[i for i in range(10000)]
print(type(l))  #リストである

となりリスト型であることが分かる。次にジェネレーターでは

g=(i for i in range(10000))
print(type(g))   #ジェネレーター型である。
print(next(g),next(g),next(g))  #値を1つずつ出す。

となりジェネレーター型であることとnextで1つずつ値を取り出せる事がわかる。