Steven D'Aprano said:
You're wrong. Python evaluates these left-to-right, as I said.
Parentheses override operator associativity; they don't affect
evaluation order at all.
Consider:
def say(x):
print 'seen %s' % x
return x
print say(1) + say(2) * say(3)
print (say(1) + say(2)) * say(3)
Run this program and you get
seen 1
seen 2
seen 3
7
seen 1
seen 2
seen 3
9
So definitely left-to-right. Translating into reverse-Polish, say with
Dijkstra's shunting-yard algorithm, is enlightening: you get
1 2 3 * +
for the first and
1 2 + 3 *
for the second. This preserves evaluation order; indeed, this is a
general property of the shunting-yard algorithm.
Finally, I quote from the language reference (5.13 of the 2.5 version),
just to show that (this time, at least) I'm not trying to impose
unfamiliar terminology, and that Python is defined to behave like this
and I'm not relying on implementation-specific details. Alas, it also
highlights a genuine inconsistency, but one which might be considered
tolerable.
: 5.13 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.
:
: In the following lines, expressions will be evaluated in the
: arithmetic order of their suffixes:
:
: expr1, expr2, expr3, expr4
: (expr1, expr2, expr3, expr4)
: {expr1: expr2, expr3: expr4}
: expr1 + expr2 * (expr3 - expr4)
: func(expr1, expr2, *expr3, **expr4)
: expr3, expr4 = expr1, expr2
So the above example is /explicitly/ dealt with in the language
reference, if only you'd cared to look.
Not everything needs to be a one liner. If you need this, do it the old-
fashioned way:
t = foo()
if not pred(t): t = default_value
I already explained how to write it as a one-liner:
t = (lambda y: y if pred(y) else default_value)(foo())
-- [mdw]