Приоритет оператора Python с расширенным присваиванием, включая последовательность
В продолжение моего предыдущего вопроса у меня следующий. Это то же самое в Python?
a += b[1] / 2
а также
a += (b[1] / 2)
При условии что:
a
ранее был определен как floatb
это список кортежейb[1]
это кортеж с одним элементом
Точно так же мне было бы интересно узнать также поведение, если:
a
ранее был определен как floatb
список поплавков
1 ответ
Правила того, как Python анализирует выражения, определены в грамматике Python. Обратите внимание, что типы не имеют значения. На самом деле Python является динамическим типом, поэтому это означает, что во время синтаксического анализа и анализа выражения типы переменных неизвестны. Фактически, переменные имеют разные значения (с разными типами) в процессе, и строка может быть оценена несколько раз, причем переменные каждый раз несут значение другого типа.
Если мы посмотрим на грамматику, мы увидим:
expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('<<'|'>>') arith_expr)* arith_expr: term (('+'|'-') term)* term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power power: atom_expr ['**' factor] atom_expr: ['await'] atom trailer* atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
"Подписка" ([1]
в b[1]
таким образом, определяется в производственном правиле trailer
и если мы посмотрим на грамматику, это может быть только продуктом factor
, так что это означает, что /
Оператор имеет приоритет над подпиской.
Так что это означает, что:
a += b[1] / 2
эквивалентно:
a += ((b[1]) / 2)
Обратите внимание, что, поскольку Python динамически типизирован, шаг анализа (и анализа) не даст никаких гарантий того, что выражение является чувственным. Например, кортеж нельзя разделить на два. Так что это приведет к TypeError
:
>>> (2.0, 4.0) / 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'tuple' and 'int'
Для numpy
массив, однако, это имеет смысл:
>>> from numpy import array
>>> array([2.0, 4.0])/2
array([1., 2.])