循环的 Python 列表理解 [英] Python list comprehension for loops

查看:32
本文介绍了循环的 Python 列表理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 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:... 对于 'pot' 中的 y:... li.append(x+y)# li=['cp', 'co', 'ct', 'ap', 'ao', 'at', 'tp', 'to', 'tt']

因此,缩短或延长一个循环的效果与在两个嵌套循环中延长 '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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆