One liners

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Dec 7 03:28:27 CET 2013


On Fri, 06 Dec 2013 17:20:27 -0700, Michael Torrie wrote:

> On 12/06/2013 05:14 PM, Dan Stromberg wrote:
>> I'm thinking mostly of stackoverflow, but here's an example I ran into
>> (a lot of) on a job:
>> 
>> somevar = some_complicated_thing(somevar) if
>> some_other_complicated_thing(somevar) else somevar
>> 
>> Would it really be so bad to just use an if statement?  Why are we
>> assigning somevar to itself?  This sort of thing was strewn across 3 or
>> 4 physical lines at a time.

Unless you're embedding it in another statement, there's no advantage to 
using the ternary if operator if the clauses are so large you have to 
split the line over two or more lines in the first place. I agree that:

result = (spam(x) + eggs(x) + toast(x) 
          if x and condition(x) or another_condition(x)
          else foo(x) + bar(x) + foobar(x))
 
is probably better written as:

if x and condition(x) or another_condition(x):
    result = spam(x) + eggs(x) + toast(x)
else:
    result = foo(x) + bar(x) + foobar(x)


The ternary if is slightly unusual and unfamiliar, and is best left for 
when you need an expression:

ingredients = [spam, eggs, cheese, toast if flag else bread, tomato]


As for your second complaint, "why are we assigning somevar to itself", I 
see nothing wrong with that. Better that than a plethora of variables 
used only once:


# Screw this for a game of soldiers.
def function(arg, param_as_list_or_string):
    if isinstance(param_as_list_or_string, str):
        param = param_as_list_or_string.split()
    else:
        param = param_as_list_or_string


# Better.
def function(arg, param):
    if isinstance(param, str):
        param = param.split()


"Replace x with a transformed version of x" is a perfectly legitimate 
technique, and not one which ought to be too hard to follow.


> You're right that a conventional "if" block is not only more readable,
> but also faster and more efficient code.

Really? I don't think so. This is using Python 2.7:


[steve at ando ~]$ python -m timeit --setup="flag = 0" \
> "if flag: y=1
> else: y=2"
10000000 loops, best of 3: 0.0836 usec per loop

[steve at ando ~]$ python -m timeit --setup="flag = 0" "y = 1 if flag else 2"
10000000 loops, best of 3: 0.0813 usec per loop


There's practically nothing between the two, but the ternary if operator 
is marginally faster.

As for readability, I accept that ternary if is unusual compared to other 
languages, but it's still quite readable in small doses. If you start 
chaining them:

result = a if condition else b if flag else c if predicate else d 

you probably shouldn't.


-- 
Steven



More information about the Python-list mailing list