Kartik Kartik - 16 days ago 6
Python Question

List comprehension based on choices

Basically, if I were to write a function with variable return elements, like so:

def func(elem1=True, elem2=True, elem3=True, elem4=False):
x = MyClass()
ret = []
if elem1:
ret.extend([x.func1()])
if elem2:
ret.extend([x.obj1])
if elem3:
ret.extend([x.func2().attr1])
if elem4:
ret.extend(x.list_obj3)
return ret


Things get rather long and windy. Is it possible to do something like this perhaps:

def func(elem1=True, elem2=True, elem3=True, elem4=False):
x = MyClass()
return [x.func1() if elem1,
x.obj1 if elem2,
x.func2().attr1 if elem3,
x.list_obj3 if elem4]


How neat is that!?

I know this can be done:

def func(elem1=True, elem2=True, elem3=True, elem4=False):
x = MyClass()
ret = [x.func1(), x.obj1, x.func2().attr1, x.list_obj3]
choices = [elem1, elem2, elem3, elem4]
return [r for i, r in enumerate(ret) if choices[i]]


but I would like to not calculate the elements if the user does not want them; it is a little expensive to calculate some of them.

Answer

If you hide your operations in lambdas then you can use lazy evaluation:

def func(elem1=True, elem2=True, elem3=True, elem4=False):
    x = MyClass()
    return [L() for inc,L in (
            (elem1, lambda: x.func1()),
            (elem2, lambda: x.obj1),
            (elem3, lambda: x.func2().attr1),
            (elem4, lambda: x.list_obj3),
            ) if inc]
Comments