Python quirk in evaluation order

J

James Stroud

Python 2.5:

mbi136-176 211% python
*** Pasting of code with ">>>" or "..." has been enabled.
########################################################################
## ipython ##
########################################################################
py> b = 4 if True else b
py> b
4


Isn't the right side supposed to be evaluated first?
 
R

Robert Kern

Python 2.5:

mbi136-176 211% python
*** Pasting of code with ">>>" or "..." has been enabled.
########################################################################
## ipython ##
########################################################################
py> b = 4 if True else b
py> b
4


Isn't the right side supposed to be evaluated first?

The right side of the assignment or the if-else expression? The "expr1 if
condition else expr2" expression evaluates condition, then either expr1 or expr2
depending on the result. The other expression is unevaluated.
Traceback (most recent call last):
Traceback (most recent call last):
5

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
A

Albert Hopkins

Python 2.5:

mbi136-176 211% python
*** Pasting of code with ">>>" or "..." has been enabled.
########################################################################
## ipython ##
########################################################################
py> b = 4 if True else b
py> b
4


Isn't the right side supposed to be evaluated first?

Yes, the right hand side of the '=', which is evaluated from LtoR.
From the Language Reference:

Python evaluates expressions from left to right. Notice that
while evaluating an assignment, the right-hand side is evaluated
before the left-hand side.

So the right-hand side of the '=' is evaluated first:

4 if True else b

And that's evaluated from left to right:

4

Therefore:

b = 4
 
P

Peter Otten

James said:
py> b = 4 if True else b
py> b
4
Isn't the right side supposed to be evaluated first?

Perhaps it becomes clearer if you change it a bit:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'whatever' is not defined

I. e. the else clause is never evaluated at all.

Peter
 
D

Dave Angel

James said:
<div class="moz-text-flowed" style="font-family: -moz-fixed">Python 2.5:

mbi136-176 211% python
*** Pasting of code with ">>>" or "..." has been enabled.
########################################################################
## ipython ##
########################################################################
py> b = 4 if True else b
py> b
4


Isn't the right side supposed to be evaluated first?

I don't have a clue what value you expected b to have. The if/else
ternary expression is roughly equivalent to:
if True:
b = 4
else
b = b
The first part to be evaluated is the if expression, which is hard-coded
to True. Then the part to the left will be used for the expression
result, and the part on the right ignored. This is because of
short-circuit rules.

Try this one for size:
b = 22 if True else I.am.Not.Being.Evaluated(4.4)

The else clause does need to be a syntactically valid expression, but
it's not evaluated unless the if-expression is false.

DaveA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,201
Messages
2,571,048
Members
47,650
Latest member
IanTylor5

Latest Threads

Top