"""Speed tester for Python list lookup. """ import timeit NUMBER = 10000 setup = """ Start, Middle, End = map(tuple, ('Start', 'Middle', 'End')) ls = [Start] + [tuple('Foo')] * 500 + [Middle] + [tuple('Bar')] * 500 + [End] """ print("Time in us to find an exact match (begin, middle, end):") print( min(timeit.repeat('Start in ls', setup, number=NUMBER))/NUMBER*1e6, min(timeit.repeat('Middle in ls', setup, number=NUMBER))/NUMBER*1e6, min(timeit.repeat('End in ls', setup, number=NUMBER))/NUMBER*1e6, ) print("Time in us to find an equal match (begin, middle, end):") print( min(timeit.repeat('tuple("Start") in ls', setup, number=NUMBER))/NUMBER*1e6, min(timeit.repeat('tuple("Middle") in ls',setup, number=NUMBER))/NUMBER*1e6, min(timeit.repeat('tuple("End") in ls', setup, number=NUMBER))/NUMBER*1e6, ) print("Time if not found:") print(min(timeit.repeat('tuple("X") in ls', setup, number=NUMBER))/NUMBER*1e6) print("And now for an object that has no __equal__:") setup = """ class Thing: pass Start, Middle, End = Thing(), Thing(), Thing() ls = [Start] + [Thing()] * 500 + [Middle] + [Thing()] * 500 + [End] """ print("Time in us to find a thing (begin, middle, end):") print( min(timeit.repeat('Start in ls', setup, number=NUMBER))/NUMBER*1e6, min(timeit.repeat('Middle in ls', setup, number=NUMBER))/NUMBER*1e6, min(timeit.repeat('End in ls', setup, number=NUMBER))/NUMBER*1e6, ) print("Time if not found:") print(min(timeit.repeat('Thing() in ls', setup, number=NUMBER))/NUMBER*1e6) """Text for issue: When doing an operation that does linear search through a container, the interpreter check all items one by one, first checking identity and then equality. In python, you effectively get: class myContainer: def __contains__(self, obj): for i in range(len(self)): if self[i] is obj: return True if self[i]==obj: return True return False My proposal is to change this to: class myContainer: def __contains__(self, obj): for i in range(len(self)): if self[i] is obj: return True for i in range(len(self)): if self[i]==obj: return True return False The net effect would be approximately: - if the object is exactly in the container, the speedup is 50%. - if the object is not in the container, there is no difference. - if an object is in the container that is equal to the object, it will be slower, but not much. """