bisect_left on first item of list within list, Python 3

Question:

I have a list like this for example:

L = [(0, "test", "value"), (0, "test2", "value2")]

and I need to = bisect_left the first item of each tuple to find an index in the list. However, I can’t think of a way of doing this without creating a list of all of these first items before hand:

exampleList = [L[i][0] for i in range(len(L))]

any ideas on another way to do this as it works but when my list gets to 5000 items long it is very slow and I need a faster way of doing it?

Asked By: Ollu_

||

Answers:

Python has a builtin bisect_left, you can use it. You don’t need to build the whole intermediate list, you just need a lazy object that retrieves the first item from the tuple at that position.

Something simple like:

class Proxy(object):
    def __getitem__(self, item):
        return L[item][0]

Beginning with Python 3.10’s bisect you can use a key function for the search, so a wrapper is no longer required. In your case it would be key=operator.itemgetter(0).

Answered By: wim
import bisect
L = [(0, "test", "value"), (1, "test2", "value2"),(3,"test3","value3")]
print (bisect.bisect_left(L,(2,)))

python deals with tuple comparisons great… just pass it (2,"asd","dsa") or even just (2,) (or whatever your index location item you are trying to find)

or you could pass it (0,"asd","value") and it would know to put it to the left of the other (0,"test","value") item tuple … or (0,"zzzz","value") and it would know to put it to the right of that item

Answered By: Joran Beasley
L = [(0, "test1", "value1"), (1, "test2", "value2"), (3, "test3", "value3")]

From Python 3.10

print(bisect_left(L, 4, key = itemgetter(0))) # output : 3

For below Python 3.10 another way is to use zip function

a, _, _ = zip(*L)

print(bisect_left(a, 2)) # output : 2
print(bisect_left(a, 4)) # output : 3
Answered By: Midhilesh Momidi