NameError в Python Вложено для циклов понимания списка - PullRequest
0 голосов
/ 29 сентября 2018

Scenerio:

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]]

Я просто хочу знать, что здесь на самом деле происходит.

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Правильно, оно оценивается слева направо.Чтобы добавить ответы других, я посмотрел официальное объяснение в документации .

Список представлений имеет форму:

 [ 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.
0 голосов
/ 29 сентября 2018

этот код

j for j in range(i) for i in range(6) 

так же, как:

for j in range(i):
    for i in range(6):
        j

внешний цикл использует i до того, как он определен, поэтому NameError произошло, т. Е. Ваше убеждение "самое правильноеfor is external "неправильно".

Вы можете использовать этот код

[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
...