场景:
for i in range(6):
for j in range(i):
j
AFAIK,在列表理解中,最右边的for
是外部的,所以,我认为以下代码可以工作:
[ j for j in range(i) for i in range(6)]
但令我惊讶的是,它抛出了NameError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
我想知道为什么它不起作用。是因为python计算从 Left到Right 的表达式吗? 原因,我已经通过使用括号解决了该问题:
[ (j for j in range(i)) for i in range(6)]
输出一堆生成器表达式:
[<generator object <listcomp>.<genexpr> at 0x7f3b42200d00>, <generator object <listcomp>.<genexpr> at 0x7f3b42200d58>, <generator object <listcomp>.<genexpr> at 0x7f3b42200db0>, <generator object <listcomp>.<genexpr> at 0x7f3b42200e08>, <generator object <listcomp>.<genexpr> at 0x7f3b42200e60>, <generator object <listcomp>.<genexpr> at 0x7f3b42200eb8>]
要探索这些生成器表达式中的内容,我们可以将它们简单地转换为列表,即
[ list(j for j in range(i )) for i in range(6)]
并且输出符合预期:
[[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]]
我只想知道这里真正发生了什么。
答案 0 :(得分:4)
正确,从左到右进行评估。要添加其他人的答案,我查找了the official explanation in the documentation。
列表推导的格式为:
[ expression for expr in sequence1
for expr2 in sequence2 ...
for exprN in sequenceN
if condition ]
for…in
子句包含要迭代的序列。的 序列不必具有相同的长度,因为它们不是 并行迭代,但从从左向右;这是解释 在以下段落中将更加清楚。的要素 生成的列表将是表达式的连续值。决赛 if子句是可选的;如果存在,则仅对表达式求值, 如果条件为真,则添加到结果中。为了使语义非常清楚,列表理解是等效的 以下Python代码:
for expr1 in sequence1:
for expr2 in sequence2:
...
for exprN in sequenceN:
if (condition):
# Append the value of
# the expression to the
# resulting list.
答案 1 :(得分:0)
此代码
j for j in range(i) for i in range(6)
就像:
for j in range(i):
for i in range(6):
j
外部循环在定义之前使用i
,因此发生NameError
,即您认为“最合适的是外部的”是错误的。
您可以使用此代码
[j for i in range(6) for j in range(i)]
以及以下代码为何起作用
[ (j for j in range(i)) for i in range(6)]
# parentheses make it work like this
for i in range(6):
for j in range(i):
j