Is there a standard binary search with overridable comparisons?

markscottwright markscottwright at gmail.com
Tue Jun 17 22:55:35 CEST 2008


I've got an ordered list of MyClasses that I want to be able to do
binary searches on, but against a tuple.  MyClass has valid
__lt__(self, rhs) and __eq__(self, rhs) member functions that work
when rhs is a tuple.

This works:
l = [MyClass(..), MyClass(..), ...]
l.find((a,b))

But this doesn't:
bisect.bisect(l, (a,b))

I'm assuming this is because inside bisect, it does 'key < list[x]'
rather than 'list[x] < key', so it's the tuple's __lt__ that is
called, rather than MyClass's tuple.

Is there a way around this?  Can I monkeypatch a new __lt__ into the
tuple class?

Here's some sample code that demonstrates the problem (it uses ints
rather than tuples, but the

import bisect
class MyC:
    def __init__(self, v):
        self.v = v

    def __lt__(self, rhs):
        return self.v < rhs

# cant search for int in a list of MyC's
l = sorted([MyC(x) for x in range(1000)])
bisect.bisect(l, 40)
1001 # AKA not found

# but, I can search for MyC in a list of ints
l = sorted(range(1000))
bisect.bisect(l, MyC(40))
41



More information about the Python-list mailing list