Steven D'Aprano <steve-remove-t...@cybersource.com.au> writes: > On Wed, 17 Nov 2010 16:31:40 +0000, Mark Wooding wrote: > > > But I don't think that's the big problem with this proposal. The real > > problem is that it completely changes the evaluation rule for the > > conditional expression. (The evaluation rule is already pretty screwy: > > Python is consistently left-to-right -- except here.) > > Not quite... > > >>> 1+2*3 > 7 > >>> (1+2)*3 > 9
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] -- http://mail.python.org/mailman/listinfo/python-list