Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a "Pythonic" way of creating a list with conditional items?

I've got this block of code in a real Django function. If certain conditions are met, items are added to the list.

ret = []

if self.taken():
    ret.append('taken')

if self.suggested():
    ret.append('suggested')

#.... many more conditions and appends...

return ret

It's very functional. You know what it does, and that's great...
But I've learned to appreciate the beauty of list and dict comprehensions.

Is there a more Pythonic way of phrasing this construct, perhaps that initialises and populates the array in one blow?

like image 725
Oli Avatar asked Mar 22 '23 18:03

Oli


2 Answers

Create a mapping dictionary:

self.map_dict = {'taken': self.taken,
                 'suggested': self.suggested,
                 'foo' : self.bar}
[x for x in ['taken', 'suggested', 'foo'] if self.map_dict.get(x, lambda:False)()]

Related: Most efficient way of making an if-elif-elif-else statement when the else is done the most?

like image 200
Ashwini Chaudhary Avatar answered Apr 07 '23 09:04

Ashwini Chaudhary


Not a big improvement, but I'll mention it:

def populate():
    if self.taken():
        yield 'taken'
    if self.suggested():
        yield 'suggested'

ret = list(populate())

Can we do better? I'm skeptical. Clearly there's a need of using another syntax than a list literal, because we no longer have the "1 expression = 1 element in result" invariant.


Edit:

There's a pattern to our data, and it's a list of (condition, value) pairs. We might try to exploit it using:

[value
 for condition, value
 in [(self.taken(), 'taken'),
     (self.suggested(), 'suggested')]
 if condition]

but this still is a restriction for how you describe your logic, still has the nasty side effect of evaluating all values no matter the condition (unless you throw in a ton of lambdas), and I can't really see it as an improvement over what we've started with.

like image 44
Kos Avatar answered Apr 07 '23 07:04

Kos