循环的 Python 列表理解 [英] Python list comprehension for loops
问题描述
我正在阅读 Python wikibook 并对此部分感到困惑:><块引用>
列表推导支持多个 for 语句.它会依次评估所有对象中的项目并将循环如果一个物体比其他物体长,则在较短的物体上.
>>>item = [x+y for x in 'cat' for y in 'pot']>>>打印项目['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']
我了解嵌套 for 循环的用法,但我不明白
<块引用>...并且会循环如果一个对象比其他对象长,则在较短的对象上
这是什么意思?(更短,更长...)
这些类型的嵌套循环创建了笛卡尔两个序列的乘积.试试看:
<预><代码>>>>[x+y 代表 'cat' 中的 x 代表 'potty' 中的 y]['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'(即'cat'部分中的for x)与外部
for x in 'cat':
在这个例子中:
因此,缩短或延长一个循环的效果与在两个嵌套循环中延长 'x' 或 'y' 循环的效果相同:
<预><代码>>>>里=[]>>>对于 'catty' 中的 x:... 对于 'pot' 中的 y:... li.append(x+y)...>>>li==[x+y for x in 'catty' for y in 'pot']真的在每种情况下,较短的序列都会再次循环,直到用完较长的序列.这与 zip
不同,其中配对将在较短序列的末尾终止.
编辑
嵌套循环与 zip 之间似乎存在混淆(在评论中).
嵌套循环:
如上图所示:
[x+y for x in '12345' for y in 'abc']
与两个嵌套的 'for' 循环相同,'x' 是外循环.
嵌套循环会在外层循环次数的x
范围内执行内层y
循环.
所以:
<预><代码>>>>[x+y for x in '12345' for y in 'ab']['1a', '1b', # x 循环中的 '1''2a', '2b', # '2' 在 x 循环中,b 在 y 循环中'3a', '3b', # x 循环中的 '3',返回 y 循环中的 'a''4a', '4b', # 以此类推'5a', '5b']您可以使用 itertools 的 product 获得相同的结果:
<预><代码>>>>从 itertools 导入产品>>>[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直到最长的序列用完,但结果不同:
<预><代码>>>>导入迭代工具>>>[x+y for x,y in itertools.zip_longest('12345','ab',fillvalue='*')]['1a', '2b', '3*', '4*', '5*']I'm reading the Python wikibook and feel confused about this part:
List comprehension supports more than one for statement. It will evaluate the items in all of the objects sequentially and will loop over the shorter objects if one object is longer than the rest.
>>>item = [x+y for x in 'cat' for y in 'pot'] >>>print item ['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']
I understand the usage of nested for loops but I don't get
...and will loop over the shorter objects if one object is longer than the rest
What does this mean? (shorter, longer...)
These type of nested loops create a Cartesian Product of the two sequences. Try it:
>>> [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']
The inner 'x' in the list comprehension above (ie, the for x in 'cat'
part) the is the same as the outer for x in 'cat':
in this example:
>>> li=[]
>>> for x in 'cat':
... for y in 'pot':
... li.append(x+y)
# li=['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']
So the effect of making one shorter or longer is the same as making the 'x' or 'y' loop longer in two nested loops:
>>> 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
In each case, the shorter sequence is looped over again until the longer sequence is exhausted. This unlike zip
where the pairing would be terminated at the end of the shorter sequence.
Edit
There seems to be confusion (in the comments) about nested loops versus zip.
Nested Loops:
As shown above, this:
[x+y for x in '12345' for y in 'abc']
is the same as two nested 'for' loops with 'x' the outer loop.
Nested loops will execute the inner y
loop the range of x
in the outer loop times.
So:
>>> [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']
You can get the same result with product from itertools:
>>> from itertools import product
>>> [x+y for x,y in product('12345','ab')]
['1a', '1b', '2a', '2b', '3a', '3b', '4a', '4b', '5a', '5b']
Zip is similar but stops after the shorter sequence is exhausted:
>>> [x+y for x,y in zip('12345','ab')]
['1a', '2b']
>>> [x+y for x,y in zip('ab', '12345')]
['a1', 'b2']
You can use itertools for a zip that will zip until the longest sequence is exhausted, but the result is different:
>>> import itertools
>>> [x+y for x,y in itertools.zip_longest('12345','ab',fillvalue='*')]
['1a', '2b', '3*', '4*', '5*']
这篇关于循环的 Python 列表理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!