Приоритет оператора Python

В документах Python говорится, что * и / имеют тот же приоритет.
Я знаю, что выражения в Python оценены слева направо.

Я могу положиться в этом и предположить, что jj/m всегда равен (jj)/m предотвращение круглых скобок?
Если это верно, я могу предположить, что это содержит для операторов с тем же приоритетом в целом?


PS: вопрос, поскольку это хорошо для моих целей, я приехал в него при чтении кода только для целого числа (как вышеупомянутый пример) без круглых скобок, которые в то время выглядели много подозрительными мне.

9
задан Lord British 25 July 2010 в 21:34
поделиться

3 ответа

Да - разные операторы с одинаковым приоритетом левоассоциативны; то есть будут обрабатываться два крайних левых элемента, затем результат, третий элемент и так далее.

Исключением является оператор ** :

>>> 2 ** 2 ** 3
256

Кроме того, операторы сравнения ( == , > и т. Д.) Не работают в ассоциативным образом, но вместо этого преобразуйте x [cmp] y [cmp] z в (x [cmp] y) и (y [cmp] z) .

14
ответ дан 4 December 2019 в 07:22
поделиться

Но если это двусмысленно для вас - кодера - а это должно быть так, потому что вы должны спросить, то ожидайте, что это будет по крайней мере так же двусмысленно для читателя, и потратьте пару октетов для ясности.

Опираться на правила старшинства - это здорово, если вы компилятор.

добавлены ответы на комментарии:

Для человека, читающего код, который столкнулся с двусмысленностью, требующей сторонней консультации для гарантии, вы должны предположить, что следующий читатель будет менее подкован, чем вы, и сэкономить им усилия и избежать человеческой ошибки при разборе той же конструкции и добавить скобки за них.

Так получилось, что даже принятый ответ оказался неверным (в обосновании, а не в следствии, см. первый комментарий), о чем я не знал, как и часть тех, кто его проголосовал.

Что касается утверждения о базовой алгебре, то конкретный пример, использованный в ОП, поучителен. Независимо от старшинства оператора выражение j * (j / m) алгебраически идентично (j * j) / m. К сожалению, алгебра Python является лишь приближением к "идеальной платоновской" алгебре, которая может дать неверные ответы для любой формы в зависимости от величин j и m. Например:

>>> m = 1e306
>>> m
1e+306
>>> j = 1e307
>>> j
9.9999999999999999e+306
>>> j / m
10.0
>>> j*j
inf
>>> j * (j / m)
1e+308
>>> (j * j) / m
inf
>>> ((j * j) / m) == (j * (j/m))
False

Таким образом, действительно, свойство идентичности квазиалгебры Python (и моего FPU) не выполняется. И это может быть иначе на вашей машине, поскольку, как отмечается в документации:

Числа с плавающей запятой реализованы с помощью double в C. Все ставки на их точности не делаются, если только вы не знаете если только вы не знаете машину, с которой работаете.

Можно утверждать, что не стоит работать на волосатой грани переполнения, и в какой-то степени это правда, но вырванное из контекста выражение является неопределенным при одном порядке операций и "правильным" при другом.

13
ответ дан 4 December 2019 в 07:22
поделиться

Короткий ответ: да.

В документации по Python сказано следующее:

Операторы в одном блоке имеют одинаковый приоритет. Если синтаксис не указан явно, операторы являются бинарными. Операторы в одной и той же ячейке группируются слева направо (за исключением сравнений, включая тесты, которые имеют одинаковый приоритет и группируются слева направо... и экспоненции, которая группируется справа налево).

Другими словами, ответ на ваш вопрос - да, операторы с одинаковым старшинством будут группироваться слева направо, кроме сравнения, которое цепочку, а не группу:

>>> x = 0
>>> y = 0
>>> x == y == True
False
>>> (x == y) == True
True
>>> x == (y == True)
True

и экспоненции:

>>> 2 ** 2 ** 3
256
>>> (2 ** 2) ** 3
64
>>> 2 ** (2 ** 3)
256

Кроме того, при присваивании правая часть оценивается раньше левой:

>>> x = 1
>>> y = x = 2
>>> y
2
3
ответ дан 4 December 2019 в 07:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: