For review: PEP 308 - If-then-else expression

Paul Moore gustav at morpheus.demon.co.uk
Sat Feb 8 17:15:05 EST 2003


Andrew Koenig <ark at research.att.com> writes:

> In effect, the problem is that the surrounding context has to
> be duplicated on both sides of the if.  Which means that the
> argument in favor of an if-then-else expression gets stronger
> as the surrounding context grows.

That's equally an argument in favour of keeping the surrounding
context small. But arguing in these terms is too theoretical to be
compelling either way.

> Consider:
>
>    val = map(lambda x: <something>, y)
>
> Now imagine that the <something> contains a conditional, such as
>
>    val = map(lambda x: str(x) if x >= 0 else "(" + str(-x) + ")", y)
>
> It's pretty clear what this does:

It want' to me at first reading. I find map and lambda pretty
unreadable. That's just personal preference, but basically *every*
argument about readability of conditional expressions is a personal
preference issue.

Let's rewrite in terms of a list comprehension, for my benefit.

    val = [ str(x) if x >= 0 else "(" + str(-x) + ")" for x in y ]

Nope, not much better. The combination of ifs and fors is very hard to
parse mentally (I even went to the language spec to make sure that
[ expr if expr ] (missing the for clause) wasn't a valid list
comprehension. That's got to be a bad sign).

> It generates a string representation for the values in y, putting
> the negative values in parentheses rather than putting a sign in
> front of them.

OK, that's understandable.

> In order to change this to an if statement, you must either repeat
> the context or introduce temporaries, such as
>
>         def f(x):
>             if x >= 0:
>                 return x
>             else:
>                 return "(" + str(-x) + ")"
>         val = map(f, y)

I have to say that using "unrealistic" names like f, x, and y is an
unfair way to make your point. In a real application, there would be
much more readable names. Assuming we're talking a financial
application (that's where I'd expect negative numbers to be displayed
like this) I'd call f something like "display_form". Then you have

         def display_form(value):
             if value >= 0:
                 return value
             else:
                 return "(" + str(-value) + ")"
         val = map(display_form, profits)

You may not like this any better, but it's a more honest
representation of the argument for why conditional expressions are not
essential. (And I don't believe that I am particularly good at
choosing names for things - someone with a better flair for this, and
a good thesaurus, could probably come up with something even better).

Yes, you still need a "temporary" (assuming it genuinely *is*
temporary, and you never need to perform this computation again). But
now, it's a temporary *concept* rather than just a temporary function.
And understanding the concepts in a piece of code is important whether
or not you use named functions to express them.

> Examples such as this are why I say that if-then-else expressions are
> particularly useful in conjunction with lambda expressions.

It's still personal preference.

Oddly, the only argument I find even remotely compelling is the lines
of code one (which most people would say is the weakest). Less lines
of code means more code visible at one time, which means you have a
better overall view of the control flow of a function. But I've never
seen Python code with functions long enough for that to matter in
practice.

Maybe it all boils down to how finely you decompose things. The more
you do, the less benefit there is to a conditional expression.

OK, let's forget this and look at optimising the Python function call
sequence to be so fast we don't care any more :-)

Paul.
-- 
This signature intentionally left blank




More information about the Python-list mailing list