Reputation: 339
Example : 10 ** 4*3 ** 2
Our teacher said python first calculates 3**2
and then 10**4
and then multiplies the answers.
But if both side of the multiplication have same order of precedence and python reads from left to right, doesn’t it do 10**4
first and then 3**2
?
(My question is not about the order or precedence of operations as both side have same order of precedence)
Upvotes: 2
Views: 210
Reputation: 530843
Your teacher is wrong. From https://docs.python.org/3/reference/expressions.html#evaluation-order:
6.15. Evaluation order
Python evaluates expressions from left to right. Notice that while evaluating an assignment, the right-hand side is evaluated before the left-hand side.
The *
has two expressions as its operands, 10**4
and 3**2
. The left operand, 10**4
is evaluated first, followed by the right operand, 3**2
.
Your teacher may be confused with a chain of exponentiations like 2 ** 3 ** 4
. Here the "outer" exponentiation has two arguments 2
and 3 ** 4
(rather than 2**3
and 4
, because of right associativity). However, the 2
is still evaluated before 3**4
.
For a simple expression like this, it doesn't really matter. But it could matter if one or both operands involved function calls with side effects. Consider something contrived like lambda: print(3) or 3)() + (lambda: print(4) or 4)()
. The value of the expression is 7 either way, but the order in which the print
functions are called will affect the output. Python, though, guarantees that 3
will be output before 4
.
Some languages (notably C, IIRC) don't specify an order of evaluation, so it is an implementation detail whether the left or right is evaluated first. This means you can't predict the value of something like i=3; j=(i++)*i
; j
could be either 3*3 == 9
or 4*3 == 12
, depending on whether i
is incremented before or after the right-hand operand is evaluated. (I don't recall if this is considered undefined behavior or implementation-defined behavior, though.)
Upvotes: 2
Reputation: 34252
We can easily test it:
class C:
def __init__(self, v):
self.v = v
def __pow__(self, x):
print(f'eval {self.v} ** {x}')
return self.v ** x
>>> C(1) ** 2 * C(4) ** 5
eval 1 ** 2
eval 4 ** 5
1024
In short, your teacher is wrong, at least for Python 3.7. In any case, regardless of whether it's true, I'd never rely on the order here, since those assumptions make the code less readable.
Upvotes: 1