这种嵌套循环创建两个序列的
笛卡尔积。试一下:
>>> [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)
因此,使一个循环变短或变长的效果与使两个嵌套循环中的“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']
这与两个嵌套的“for”循环相同,其中“x”为外部循环。
嵌套循环将执行内部的y
循环,在外部循环中的x
范围内执行。
所以:
>>> [x+y for x in '12345' for y in 'ab']
['1a', '1b',
'2a', '2b',
'3a', '3b',
'4a', '4b',
'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']
你可以使用
itertools进行zip,直到最长序列用尽,但结果是不同的:
>>> import itertools
>>> [x+y for x,y in itertools.zip_longest('12345','ab',fillvalue='*')]
['1a', '2b', '3*', '4*', '5*']
zip
的行为混淆了。 - user2357112