Scenerio:
for i in range(6):
for j in range(i):
j
AFAIK, in list comprehension the right most for
is the outer one so, I thought the following code will work:
[ j for j in range(i) for i in range(6)]
But to my surprise, it throws a NameError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
I wonder why it didn't work. Is it because python evaluates expression from Left to Right? Cause, I have resolved the issue by using parenthesis:
[ (j for j in range(i)) for i in range(6)]
which outputs a bunch of generator expressions:
[<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>]
To explore what is inside these generator expressions we can simply cast them into lists i.e.
[ list(j for j in range(i )) for i in range(6)]
and the output is as expected:
[[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]]
I just want to know what is really happening here.
this code
just like :
outer loop uses
i
before it is defined, soNameError
occurred, i.e. your belief "the right most for is the outer one" is wrong.You can use this code
and why below code work
Correct, it's evaluated from left to right. To add the others' answers, I looked up the official explanation in the documentation.