Dictionaries are usually O(1) for lookups.
It's perfectly acceptable to have a class that returns a constant for it's hash, but this degrades dictionary lookups to be linear.
eg.
class dumbint(int):
def __hash__(self):
return 0
$ python -m timeit -s 'class dumbint(int):__hash__ = lambda x:0' -s 'd={dumbint(i):i for i in range(100)}' 'dumbint(-1) in d'
100000 loops, best of 3: 3.64 usec per loop
$ python -m timeit -s 'class dumbint(int):__hash__ = lambda x:0' -s 'd={dumbint(i):i for i in range(1000)}' 'dumbint(-1) in d'
10000 loops, best of 3: 31.7 usec per loop
$ python -m timeit -s 'class dumbint(int):__hash__ = lambda x:0' -s 'd={dumbint(i):i for i in range(10000)}' 'dumbint(-1) in d'
1000 loops, best of 3: 803 usec per loop
strings have a good hash function, so you'll get O(1) lookups for exact matches. Searching for a substring in the keys is a much more difficult problem.