I have a list of tuples, e.g.
>>> l = [ ("a",1), ("b",2), ("c",3) ]
and I can assume that elements are unique. Now I would like to get the first element of that tuple whose second element is 2
(which is 'b'
in this example). First attempt is:
>>> [ x for x, y in l if y == 2 ][0]
'b'
This seems somewhat cumbersome considering this creates a second list only to index the 0th element. Another way of doing this is to reverse all tuples in the given list l
and build a dictionary, then index that dictionary:
>>> dict([ (y, x) for x, y in l ])[2]
'b'
This seems even more awkward considering the amount of data shuffling involved in reversing the list and creating a dictionary. Lastly, the most verbose but perhaps fastest way to do this is to simply iterate over the list:
>>> def get(l) :
... for x, y in l :
... if y == 2 :
... return x
... assert not "Should not happen."
...
>>> get(l)
'b'
My question is: are there any better and more pythonic ways to searching through this list?
Try this:
next(x for x in l if x[1] == 2)[0]
The advantage of using next()
is that we iterate only over the minimum amount of elements required for finding what we're looking for, so no, it's not equivalent to creating a whole new list using a list comprehension and then returning the first element.
You can also use next()
:
In [1]: l = [("a", 1), ("b", 2), ("c", 3)]
In [2]: next(a for a, b in l if b == 2)
Out[2]: 'b'
Note that it would throw StopIteration
exception if nothing found unless a default
is supplied:
In [3]: next(a for a, b in l if b == 100)
---------------------------------------------------------------------------
StopIteration
Traceback (most recent call last)
<ipython-input-38-14fe91d87aab> in <module>()
----> 1 next(a for a, b in l if b == 100)
StopIteration:
In [4]: next((a for a, b in l if b == 100), 0)
Out[4]: 0
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