[Python-Dev] Adding a conditional expression in Py3.0
Nick Coghlan
ncoghlan at gmail.com
Wed Sep 21 00:30:13 CEST 2005
Steven Bethard wrote:
> Guido van Rossum wrote:
>
>>I think I'd prefer (if <expr> then <expr> else <expre>) i.e. no
>>colons. None of the other expression forms (list comprehensions and
>>generator expressions) involving statement keywords use colons.
>
>
> FWIW, I find this quite intuitive. It follows the same pattern as LCs
> and GEs -- remove the colons and add parentheses (or brackets for
> LCs). So I'm +1.
*But*, in LC's and GE's, the body of the main clause of the statement is also
pulled out and placed in front of the keyword:
def gen():
for VAR in ITERABLE:
if COND:
yield EXPR
becomes:
gen = (EXPR for VAR in ITERABLE if COND)
This makes sense to me, because the most important thing in the generator
expression is the way each element is populated - the source iterable and the
filtering condition do matter, but they aren't as important.
It also makes the expression forms more declarative in nature, rather than
being procedural statements embedded inside an expression.
Notice also that, in this case, if ITERABLE is empty, or COND always evaluates
false in boolean context, then EXPR is never executed - in other words, Python
already has precedent for out of order code execution in expression evaluation.
Guido's original PEP 308 proposal worked much the same way:
if COND:
x = EXPR1
else:
x = EXPR2
became:
x = (EXPR1 if COND else EXPR2)
I see this as similar in spirit to the current form of LC's and GE's - the
most important things are the two possible values rather than the condition
for choosing between them, and this form makes them clearly visible at the
start and end of the expression, rather than embedding one of them in the
middle. The post-filtered form is also similarly declarative rather than
procedural.
This version doesn't need a separate 'elif' form - elif can be written as:
x = (EXPR1 if COND1 else EXPR2 if COND2 else EXPR3)
Note that the keyword count is no higher than if 'elif' was used, because the
'then' keyword isn't needed:
x = (if COND1 then EXPR1 elif COND2 then EXPR2 else EXPR3)
Here's Raymond's problematic example using this original PEP 308 form:
def real(self):
'Return a vector with the real part of each input element'
# do not convert integer inputs to floats
return self.map(lambda z:
(z.real if type(z)==types.ComplexType else z))
And the other non-colon, keyword based proposal in PEP 308's top four:
def real(self):
'Return a vector with the real part of each input element'
# do not convert integer inputs to floats
return self.map(lambda z:
(if type(z)==types.ComplexType then z.real else z))
Another common use case would be for mutable default arguments:
x = ([] if arg is None else list(arg))
x = (if arg is None then [] else list(arg))
Basically, I'm +1 on the original PEP 308 form because it reads more naturally
(and more like LC's and GE's) to me in expression contexts, and +0 on the
"if/then/elif/else" form (because I would like a real conditional operator).
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list