Python operator precedence
The Python docs say that *
and /
have the same precedence.
Can i rely on that and assume that j*j/m
is always equal to (j*j)/m
avoiding the parentheses?
ps: The question as it is fine for my purposes, i came to it while reading integer-only code (like the above example) without parentheses, which at the time look开发者_Python百科ed a lot suspicious to me.
Yes - different operators with the same precedence are left-associative; that is, the two leftmost items will be operated on, then the result and the 3rd item, and so on.
An exception is the **
operator:
>>> 2 ** 2 ** 3
256
Also, comparison operators (==
, >
, et cetera) don't behave in an associative manner, but instead translate x [cmp] y [cmp] z
into (x [cmp] y) and (y [cmp] z)
.
But, if it is ambiguous to you - the coder - and it must be because you have to ask, then expect it will be at least as ambiguous for the reader and waste a couple octets for clarity.
Relying on precedence rules is great if you happen to be a compiler.
added responses to comments:
For the person reading code who encounters an ambiguity that requires outside consultation for assurance, you should assume that the next reader will be less savvy than you and save them the effort and avoidable human error of parsing the same construct and add the parenthesis for them.
As it happens, even the accepted answer was incorrect (in rationale, not effect, see its first comment) which I wasn't aware of and neither were a fraction of those who upvoted it.
As to the statement about basic algebra, the particular example used in the OP is instructive. Regardless of operator precedence the expression j * (j / m)
is algebraically identical to (j * j) / m
. Unfortunately, Python algebra is only an approximation of "Platonic ideal" algebra which could yield incorrect answers for either form depending on the magnitudes of j
and m
. For example:
>>> 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
So indeed the identity property of Python's (and my FPU) quasi-algebra doesn't hold. And this may be different on your machine for as the documentation notes:
Floating point numbers are implemented using double in C. All bets on their precision are off unless you happen to know the machine you are working with.
It could be claimed that one has no business working on the hairy edge of overflow, and that's true to some extent, but removed from context the expression is indeterminate given one order of operations and "correct" under another.
Short answer: yes.
The Python documentation says the following:
Operators in the same box have the same precedence. Unless the syntax is explicitly given, operators are binary. Operators in the same box group left to right (except for comparisons, including tests, which all have the same precedence and chain from left to right... and exponentiation, which groups from right to left).
So in other words the answer to your question is yes, operators with the same precedence will group left to right apart from Comparisions which chain rather than group:
>>> x = 0
>>> y = 0
>>> x == y == True
False
>>> (x == y) == True
True
>>> x == (y == True)
True
and Exponentation:
>>> 2 ** 2 ** 3
256
>>> (2 ** 2) ** 3
64
>>> 2 ** (2 ** 3)
256
Also, in assignment the right-hand side is evaluated before the left-hand side:
>>> x = 1
>>> y = x = 2
>>> y
2
精彩评论