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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With