Python: tuple list search

I have a list of tuples, for example

>>> l = [ ("a",1), ("b",2), ("c",3) ] 

and I can assume that the elements are unique. Now I would like to get the first element of this tuple, the second element of which is 2 (which in this example is 'b' ). First try:

 >>> [ x for x, y in l if y == 2 ][0] 'b' 

This seems a little cumbersome given that it creates a second list just to index the 0th item. Another way to do this is to undo all the tuples in a given list l and build a dictionary, and then index this dictionary:

 >>> dict([ (y, x) for x, y in l ])[2] 'b' 

This seems even more inconvenient, given the amount of data shuffling associated with translating the list and creating the dictionary. Finally, the most detailed, but perhaps the 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 search this list?

+6
source share
3 answers

Try the following:

 next(x for x in l if x[1] == 2)[0] 

The advantage of using next() is that we iterate over only the minimum number of elements needed to find what we are looking for, so no, this is not equivalent to creating a whole new list using list comprehension, and then returning the first element.

+7
source

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 will throw a StopIteration exception if nothing is found, if default not specified:

 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 
+3
source

It depends on how you want to pay, place or time. You cannot have both.

1 If we want to speed up:

 l = [ ("a",1), ("b",2), ("c",3) ] _dict = {k:v for v,k in l} print(_dict.get(2, None)) 

2 If space is limited, try another answer further or your loop.

+1
source

Source: https://habr.com/ru/post/984638/


All Articles