[英]NameError in Python Nested for loops of List Comprehension
场景:
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从左到右计算表达式吗? 因为,我已经通过使用括号解决了这个问题:
[ (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]]
我只是想知道这里到底发生了什么。
正确,它是从左到右评估的。 为了添加其他人的答案,我在文档中查找了官方解释。
列表推导式具有以下形式:
[ 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.
这段代码
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.