嵌套列表中的不同输出对循环的理解和等效

时间:2014-01-07 19:11:21

标签: python list list-comprehension

我正在学习列表理解,我无法理解,为什么在列表理解和循环等效的情况下输出是不同的。

列表理解:

>>> [b for b in range(0,a) for a in range(1,5)]
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]

相当于循环:

>>> list = []
>>> for a in range(1,5):
...     for b in range(0,a):
...         list.append(b)
...
>>> list
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]

请帮助我理解为什么他们提供不同的输出以及阅读列表理解的正确方法。

2 个答案:

答案 0 :(得分:3)

你需要颠倒你的“链式”for循环的顺序:

[b for a in range(1,5) for b in range(0,a)]

(我必须承认我最初也发现这种排序反直觉......)

一般来说,这是:

[ EXP for VAR1 in SEQ1 for VAR2 in SEQ2 ]

转换为:

for VAR1 in SEQ1:
  for VAR2 in SEQ2:
     ...

因此,当您执行[b for b in range(0,a) for a in range(1,5)]时,在评估a时会使用以前具有的值range(0,a)。 (如果先前未定义a,则会引发错误。)

答案 1 :(得分:0)

除非您先执行第二个代码,否则

第一个表达式会产生错误:

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

如果a等于4,您可以获得结果,即如果您先执行第二个语句,则可以获得结果:

>>> list = []
>>> for a in range(1,5):
...     for b in range(0,a):
...         list.append(b)
...
>>> list
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
>>> a
4
>>> [b for b in range(0,a) for a in range(1,5)]
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]

正确的表达将是

>>> [b for a in range(1,5) for b in range(0, a)]
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]