Есть ли причина, по которой циклически проходить через неявный кортеж в цикле for
нормально, но когда вы делаете это в понимании, вы получаете синтаксическую ошибку?
Например:
for i in 'a','b','c':
print(i)
'a'
'b'
'c'
Но в понимании:
>>> [i for i in 'a','b','c']
File "<stdin>", line 1
[i for i in 'a','b','c']
^
SyntaxError: invalid syntax
Есть причина для этого? Я не был уверен в правильной терминологии, поэтому мои поиски не дали ничего полезного.
< Сильный > Update :
Согласно комментариям, этот синтаксис является действительным для Python 2.x, но не для Python 3.x.
3 ответа
Это изменилось в Python3, главным образом для того, чтобы сделать списки более совместимыми с выражениями генератора.
При использовании циклов for и списков не возникает двусмысленности при использовании кортежа без скобок, поскольку первый всегда заканчивается двоеточием, а последний - закрывающей скобкой или ключевым словом for/if
.
Однако часть разработки выражений генератора требует, чтобы они могли использоваться «голыми» в качестве аргументов функции:
>>> list(i for i in range(3))
[0, 1, 2]
Что создает некоторую неоднозначность для непереносимых кортежей, потому что любые запятые могут вводить новый аргумент:
>>> list(i for i in 0, 1, 2)
File "<stdin>", line 1
SyntaxError: Generator expression must be parenthesized if not sole argument
Таким образом, кортежи всегда должны быть заключены в скобки в выражениях генератора, и то же самое ограничение теперь также применяется к спискам, чтобы сохранить последовательность.
PS :
Гидо ван Россум (Guido van Rossum) написал статью, в которой излагаются все детали по этому вопросу в своем блоге History of Python:
Я думаю, что проблема здесь: в последнем случае не так очевидно, какие объекты вы повторяете:
>>> [i for i in ('a','b','c')]
['a', 'b', 'c']
Где граница между элементами? Это массив из 3 элементов: генератор и 2 целых числа? Как это:
>>> [(i for i in 'a'),'b','c']
[<generator object <genexpr> at 0x10cefeeb8>, 'b', 'c']
for
не имеет такой двусмысленности - поэтому не нуждается в скобках.
Потому что for i in
в первом коде является другой синтаксической конструкцией, чем for i in
во втором коде.
Первый случай - это оператор for
, который имеет грамматика:
for_stmt ::= "for" target_list "in" expression_list ":" suite
["else" ":" suite]
'a', 'b', 'c'
определенно является expression_list
, так что получается.
Во втором случае, однако, встроенные for
в квадратных скобках заставляют код интерпретироваться как понимание списка, а в Python 3 списочные выражения должны иметь синтаксис:
comprehension ::= expression comp_for
comp_for ::= "for" target_list "in" or_test [comp_iter]
comp_iter ::= comp_for | comp_if
comp_if ::= "if" expression_nocond [comp_iter]
Обратите внимание, что часть после in
должна быть or_test
, но выражения с разделителями-запятыми создают списки выражений, и список выражений не может быть or_test
--- или, другими словами, or
имеет более высокий приоритет, чем запятая. Таким образом, Python считает, что понимание заканчивается запятой, поэтому три элемента списка:
i for i in 'a'
'b'
'c'
Который (если вы не поместите i for i in 'a'
в скобки), очевидно, недействителен.
Что касается того, почему это работает в Python 2 ... Я все еще ищу.
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.