2009年10月20日火曜日

リスト内包表記/2重ループ

リスト内包表記を使うと2重ループ(のようなもの)も作れます。

>>> [i + j for i in ["1","2","3"] for j in ["a","b","c"]]
['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']

まずi:1に対して、j側のループが回り、その後i:2、i:3に対してループが回っています。左側に置いたループ対象の方が外側のループとして機能します。

九九を計算してみました。でも1つのリストにすべての結果が入っているので、表っぽくないですね。
>>> [i * j for i in range(1,10) for j in range(1,10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18,
21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45
, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 2
4, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]

こうするとリストのリストになります。
>>> [[i * j for i in range(1,10)] for j in range(1,10)]
[[1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 4, 6, 8, 10, 12, 14, 16, 18], [3, 6, 9, 12, 15
, 18, 21, 24, 27], [4, 8, 12, 16, 20, 24, 28, 32, 36], [5, 10, 15, 20, 25, 30, 3
5, 40, 45], [6, 12, 18, 24, 30, 36, 42, 48, 54], [7, 14, 21, 28, 35, 42, 49, 56,
63], [8, 16, 24, 32, 40, 48, 56, 64, 72], [9, 18, 27, 36, 45, 54, 63, 72, 81]]

適当に整形してあげると、表にみえますよね。
[[1, 2, 3, 4, 5, 6, 7, 8, 9],
[2, 4, 6, 8, 10, 12, 14, 16, 18],
[3, 6, 9, 12, 15, 18, 21, 24, 27],
[4, 8, 12, 16, 20, 24, 28, 32, 36],
[5, 10, 15, 20, 25, 30, 35, 40, 45],
[6, 12, 18, 24, 30, 36, 42, 48, 54],
[7, 14, 21, 28, 35, 42, 49, 56, 63],
[8, 16, 24, 32, 40, 48, 56, 64, 72],
[9, 18, 27, 36, 45, 54, 63, 72, 81]]

もちろん、二重ループの場合も、ifによる抽出条件は使えます。

九九の表から8の倍数だけを抽出。
>>> [i * j for i in range(1,10) for j in range(1,10) if i * j % 8 == 0]
[8, 8, 16, 24, 8, 16, 24, 32, 40, 24, 48, 56, 8, 16, 24, 32, 40, 48, 56, 64, 72,
72]

重複を取り除くにはset型に変更した後、sortedでリストに戻すとよい。
>>> sorted(set([i * j for i in range(1,10) for j in range(1,10) if i * j % 8 ==
0]))
[8, 16, 24, 32, 40, 48, 56, 64, 72]

0 件のコメント:

コメントを投稿