繁体   English   中英

列表理解中的语句顺序

[英]Order of for statements in a list comprehension

在python2.7中,我试图将字符串列表中的每个项目添加到另一个项目中(例如,在列表['b','c']中的每个项目之前添加项目'a')。 如何在列表推导中添加列表列表 ,我已经确定了正确的命令,其归结为:

>>> [i for x in ['b', 'c'] for i in ['a', x]]
['a', 'b', 'a', 'c']

纯粹基于临时i和x变量,下面的版本似乎更具可读性。 但是,它给出了完全不同的结果。 为什么这不会给出相同的结果?

>>> [i for i in ['a', x] for x in ['b', 'c']]
['a', 'a', 'c', 'c']

更奇怪的是,'b'条目发生了什么?

列表推导中的for循环始终以嵌套顺序列出。 您可以使用相同的嵌套顺序将两种理解都写成常规循环; 记住,只有前首先表达for产生的最终值,所以就把该环路内。

所以[i for x in ['b', 'c'] for i in ['a', x]]变为:

for x in ['b', 'c']:
    for i in ['a', x]:
        i  # added to the final list

并且[i for i in ['a', x] for x in ['b', 'c']]变为:

for i in ['a', x]:
    for x in ['b', 'c']:
        i

如您所见,如果没有首先在列表推导之外定义x ,第二个版本将无法运行,因为否则无法创建['a', x]列表。 另请注意,否则忽略 for x in ['b', 'c'] x的内环for x in ['b', 'c'] 你得到的是i重复。 内循环中该列表中的值无关紧要, 只有循环的长度才重要

在您的情况下,您的输出将通过首先设置x = 'c'来解释; 然后你for i in ['a', 'c']为外循环得到for i in ['a', 'c'] ,内循环迭代两次所以'a'被加两次,然后i = 'c'被设置并且你得到'c'两次。

碰巧,在Python 2中,变量在列表中使用了解“泄漏”,就像常规for循环泄漏中使用的变量一样; for x in ['b', 'c']: pass使用for x in ['b', 'c']: passfor x in ['b', 'c']: passx将保持可用并绑定到'c' 这是你的x = 'c'来自的地方:

>>> [i for x in ['b', 'c'] for i in ['a', x]]
['a', 'b', 'a', 'c']
>>> i
'c'
>>> x
'c'
>>> [i for i in ['a', x] for x in ['b', 'c']]
['a', 'a', 'c', 'c']

ix反映了它们最后绑定的内容,因此当第一个( 外部 )循环遍历['a', 'c'] ,运行下一个列表理解会起作用。

从你的全局变量中删除x ,第二个列表理解根本无法运行:

>>> del x
>>> [i for i in ['a', x] for x in ['b', 'c']]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

上面的完整常规for循环版本也是如此:

>>> for i in ['a', x]:
...     for x in ['b', 'c']:
...         i
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> x = 'foo'
>>> for i in ['a', x]:
...     for x in ['b', 'c']:
...         i
... 
'a'
'a'
'foo'
'foo'

在Python 3中,列表推导在新范围内执行(就像生成器表达式,dict理解和集合理解已经在Python 2中完成)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM