Python 中的 NameError 嵌套 for 列表理解循环
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]]
我只是想知道这里究竟发生了什么。
此代码
j for j in range(i) for i in range(6)
就像:
for j in range(i):
for i in range(6):
j
外层循环在定义之前使用了i
,所以出现了NameError
,即你认为"the right most for is the outer one"是错误的。
您可以使用此代码
[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
正确,它是从左到右计算的。为了添加其他人的答案,我查找了 the official explanation in the documentation.
List comprehensions have the form:
[ expression for expr in sequence1
for expr2 in sequence2 ...
for exprN in sequenceN
if condition ]
The for…in
clauses contain the sequences to be iterated over. The
sequences do not have to be the same length, because they are not
iterated over in parallel, but from left to right; this is explained
more clearly in the following paragraphs. The elements of the
generated list will be the successive values of expression. The final
if clause is optional; if present, expression is only evaluated and
added to the result if condition is true.
To make the semantics very clear, a list comprehension is equivalent
to the following Python code:
for expr1 in sequence1:
for expr2 in sequence2:
...
for exprN in sequenceN:
if (condition):
# Append the value of
# the expression to the
# resulting list.
场景:
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]]
我只是想知道这里究竟发生了什么。
此代码
j for j in range(i) for i in range(6)
就像:
for j in range(i):
for i in range(6):
j
外层循环在定义之前使用了i
,所以出现了NameError
,即你认为"the right most for is the outer one"是错误的。
您可以使用此代码
[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
正确,它是从左到右计算的。为了添加其他人的答案,我查找了 the official explanation in the documentation.
List comprehensions have the form:
[ expression for expr in sequence1
for expr2 in sequence2 ...
for exprN in sequenceN
if condition ]
The
for…in
clauses contain the sequences to be iterated over. The sequences do not have to be the same length, because they are not iterated over in parallel, but from left to right; this is explained more clearly in the following paragraphs. The elements of the generated list will be the successive values of expression. The final if clause is optional; if present, expression is only evaluated and added to the result if condition is true.To make the semantics very clear, a list comprehension is equivalent to the following Python code:
for expr1 in sequence1:
for expr2 in sequence2:
...
for exprN in sequenceN:
if (condition):
# Append the value of
# the expression to the
# resulting list.