Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: list comprehensions vs. lambda

I want to retrieve the integer value from the sublist containing "b" as the first element (b will only appear once in the list)

Those two ways came to my mind:

foo = [["a", 5], ["b", 10], ["c", 100]]

y = filter(lambda x: x[0] == "b", foo)
print y[0][1]

z = [foo[i][1] for i in range(len(foo)) if foo[i][0] == "b"] 
print z[0]

They both work. Is any of the two preferable (regarding runtime), is there an even better third way?

like image 501
helm Avatar asked Dec 07 '22 08:12

helm


1 Answers

When the list is so small there is no significant difference between the two. If the input list can grow large then there is a worse problem: you're iterating over the whole list, while you could stop at the first element. You could accomplish this with a for loop, but if you want to use a comprehension-like statement, here come generator expressions:

# like list comprehensions but with () instead of []
gen = (b for a, b in foo if a == 'b')
my_element = next(gen)

or simply:

my_element = next(b for a, b in foo if a == 'b')

If you want to learn more about generator expressions give a look at PEP 289.


Note that even with generators and iterators you have more than one choice.

# Python 3:
my_element = next(filter(lambda x: x[0] == 'b', foo))

# Python 2:
from itertools import ifilter
my_element = next(ifilter(lambda (x, y): x == 'b', foo))

I personally don't like and don't recommend this because it is much less readable. It turns out that this is actually slower than my first snippet, but more in general using filter() instead of a generator expression might be faster in some special cases.

In any case if you need benchmarking your code, I recommend using the timeit module.

like image 115
Davide R. Avatar answered Dec 15 '22 08:12

Davide R.