これらのタイプのネストされたループは、2 つのシーケンスのデカルト積を作成します。それを試してみてください:
>>> [x+y for x in 'cat' for y in 'potty']
['cp', 'co', 'ct', 'ct', 'cy', 'ap', 'ao', 'at', 'at', 'ay', 'tp', 'to', 'tt', 'tt', 'ty']
>>> [x+y for x in 'catty' for y in 'pot']
['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt', 'tp', 'to', 'tt', 'yp', 'yo', 'yt']
上記のリスト内包表記の内側の 'x' (つまり、部分) は、この例の外側for x in 'cat'
と同じです。 for x in 'cat':
>>> li=[]
>>> for x in 'cat':
... for y in 'pot':
... li.append(x+y)
# li=['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']
したがって、一方を短くしたり長くしたりする効果は、ネストされた 2 つのループで 'x' または 'y' ループを長くすることと同じです。
>>> li=[]
>>> for x in 'catty':
... for y in 'pot':
... li.append(x+y)
...
>>> li==[x+y for x in 'catty' for y in 'pot']
True
いずれの場合も、長いシーケンスが使い果たされるまで、短いシーケンスが繰り返しループされます。zip
これは、ペアリングが短いシーケンスの最後で終了する場合とは異なります。
編集
ネストされたループと zip について (コメントで) 混乱しているようです。
ネストされたループ:
上記のように、これは次のとおりです。
[x+y for x in '12345' for y in 'abc']
'x' が外側のループである 2 つのネストされた 'for' ループと同じです。
ネストされたループは、外側のループ時間y
の範囲で内側のループを実行しx
ます。
そう:
>>> [x+y for x in '12345' for y in 'ab']
['1a', '1b', # '1' in the x loop
'2a', '2b', # '2' in the x loop, b in the y loop
'3a', '3b', # '3' in the x loop, back to 'a' in the y loop
'4a', '4b', # so on
'5a', '5b']
itertoolsのproductでも同じ結果が得られます。
>>> from itertools import product
>>> [x+y for x,y in product('12345','ab')]
['1a', '1b', '2a', '2b', '3a', '3b', '4a', '4b', '5a', '5b']
Zip は似ていますが、短いシーケンスが使い果たされた後に停止します。
>>> [x+y for x,y in zip('12345','ab')]
['1a', '2b']
>>> [x+y for x,y in zip('ab', '12345')]
['a1', 'b2']
最長のシーケンスが使い果たされるまで zip する zip にitertoolsを使用できますが、結果は異なります。
>>> import itertools
>>> [x+y for x,y in itertools.zip_longest('12345','ab',fillvalue='*')]
['1a', '2b', '3*', '4*', '5*']