Note that that finds the index to the left of the insertion point for the value given, but doesn’t perform a containment test; you have to also check that the index is in the list (instead of off the end) and that the value at the resulting index equals the value of interest to test containment. Which can be a one-liner without redundant calls (with walrus), but is a bit ugly.
(Of course, for a custom class you can just wrap it in a __contains__ method and then just use the “in” operator.)
> you have to also check that the index is in the list (instead of off the end) and that the value at the resulting index equals the value of interest to test containment
True. However, the hardest part of the binary search algorithm is implemented through bisect, so it still saves a lot of developer time.
You can do that too, using the bisect, provided you have the __len__ and __getitem__ implemented:
class C:
def __len__(self): ...
def __getitem__(self, i): ...
def __contains__(self, x):
i = bisect.bisect_left(self, x)
return i < len(self) and self[i] == x
The first two lines are setup, real code would already have done that.
You could maybe count the import, but you'd have to do that once and could do multiple bisections, so it's amortized.
Setting the variable doesn't count because you do, of course, need a variable to perform an operation on a variable. Sorting the array also wouldn't count because you can't use binary search if the array isn't sorted.
Here it is: