В документах Python говорится, что * и / имеют тот же приоритет.
Я знаю, что выражения в Python оценены слева направо.
Я могу положиться в этом и предположить, что jj/m всегда равен (jj)/m предотвращение круглых скобок?
Если это верно, я могу предположить, что это содержит для операторов с тем же приоритетом в целом?
PS: вопрос, поскольку это хорошо для моих целей, я приехал в него при чтении кода только для целого числа (как вышеупомянутый пример) без круглых скобок, которые в то время выглядели много подозрительными мне.
Да - разные операторы с одинаковым приоритетом левоассоциативны; то есть будут обрабатываться два крайних левых элемента, затем результат, третий элемент и так далее.
Исключением является оператор **
:
>>> 2 ** 2 ** 3
256
Кроме того, операторы сравнения ( ==
, >
и т. Д.) Не работают в ассоциативным образом, но вместо этого преобразуйте x [cmp] y [cmp] z
в (x [cmp] y) и (y [cmp] z)
.
Но если это двусмысленно для вас - кодера - а это должно быть так, потому что вы должны спросить, то ожидайте, что это будет по крайней мере так же двусмысленно для читателя, и потратьте пару октетов для ясности.
Опираться на правила старшинства - это здорово, если вы компилятор.
добавлены ответы на комментарии:
Для человека, читающего код, который столкнулся с двусмысленностью, требующей сторонней консультации для гарантии, вы должны предположить, что следующий читатель будет менее подкован, чем вы, и сэкономить им усилия и избежать человеческой ошибки при разборе той же конструкции и добавить скобки за них.
Так получилось, что даже принятый ответ оказался неверным (в обосновании, а не в следствии, см. первый комментарий), о чем я не знал, как и часть тех, кто его проголосовал.
Что касается утверждения о базовой алгебре, то конкретный пример, использованный в ОП, поучителен. Независимо от старшинства оператора выражение 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. Все ставки на их точности не делаются, если только вы не знаете если только вы не знаете машину, с которой работаете.
Можно утверждать, что не стоит работать на волосатой грани переполнения, и в какой-то степени это правда, но вырванное из контекста выражение является неопределенным при одном порядке операций и "правильным" при другом.
Короткий ответ: да.
В документации по 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