Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 理解列表中语句的顺序_Python_Python 2.7_List Comprehension - Fatal编程技术网

Python 理解列表中语句的顺序

Python 理解列表中语句的顺序,python,python-2.7,list-comprehension,Python,Python 2.7,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]

在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”项发生了什么?

列表理解中的
循环总是按嵌套顺序列出。你可以使用相同的嵌套顺序,将你的两个理解写成规则循环;请记住,只有位于
的第一个
之前的表达式才会生成最终值,因此请将其放入循环中

因此,
[i代表['b','c']中的x,i代表['a',x]]
变成:

for x in ['b', 'c']:
    for i in ['a', x]:
        i  # added to the final list
for i in ['a', x]:
    for x in ['b', 'c']:
        i
[i代表i在['a',x]代表x在['b',c']]
变成:

for x in ['b', 'c']:
    for i in ['a', x]:
        i  # added to the final list
for i in ['a', x]:
    for x in ['b', 'c']:
        i
如您所见,如果不首先在列表理解之外定义
x
,第二个版本将无法运行,因为否则无法创建
['a',x]
列表。还请注意,['b','c']
中x的内环
x
将被忽略。你得到的只是重复的
i
。在内部循环中,列表中的值是什么并不重要,重要的只是循环的长度

在您的情况下,您的输出将通过首先设置
x='c'
来解释;然后在['a',c']
中为i获取
,对于外部循环,内部循环迭代两次,因此
'a'
被添加两次,然后设置
i='c'
并获得
'c'
添加两次

碰巧,在Python 2中,列表理解中使用的变量是“泄漏”,就像常规
for
循环泄漏中使用的变量一样;在['b','c']:pass中为x使用
后,
x
将保持可用并绑定到
'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']
i
x
反映了它们上次绑定到的内容,因此运行下一个列表理解可以在第一个(外部)循环迭代
['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

在Python3中,列表理解在一个新的范围内执行(就像生成器表达式、dict理解和set理解在Python2中已经执行过一样)。

提示:如果在一个全新的解释器窗口中运行第二个代码,会发生什么,以前没有运行过代码的地方?嵌套列表中的
for
s与常规嵌套
for
循环中的
顺序相同-最外面的第一个。您刚刚被早期列表comp的
x
泄漏搞糊涂了(这已在3.x中修复)。@Kevin,我得到:name错误:名称“x”未定义。然而,按照这种逻辑,所有列表理解在定义变量之前都使用一个变量。在“[x代表x In…”中,第一个x是接收值的对象,尚未定义。我的理解是,在解析列表理解时,您从右到左阅读,但此示例似乎不符合该公理。例如,您列出的comp基本上是['a',x]中i的
;对于['b',c']中的x: