As per the official Python docs for in operator: For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y). However this does not seem to be true. Please see the following code: class Val: def __init__(self, val): self.val = val def __eq__(self, other): return self.val == other.val __hash__ = object.__hash__ one = Val(1) ; two = Val(2) ; three = Val(3) valSeq = [one, two, three] print("Val(2) in valSeq:\n ", Val(2) in valSeq) This prints: Val(2) in valSeq: True as expected, but the same does not work when I use Val as a key in a dictionary: valMap = {one: "ekam", two: "dve", three: "trini"} print("valMap[Val(2)]:") try: print(valMap[Val(2)]) except KeyError: print(" KeyError") print() print("Val(2) in valMap:\n ", Val(2) in valMap) This outputs: valMap[Val(2)]: KeyError Val(2) in valMap: False To investigate why this happens, I try testing what the documentation says: def inTest(obj, seq): return any(obj is test or obj == test for test in seq) print("inTest(Val(2), valMap):\n ", inTest(Val(2), valMap)) which gives: inTest(Val(2), valMap): True and sure enough, the equality test of Val(2) is satisfied as expected: def inTestStr(obj, seq): for test in seq: print(obj is test, obj == test) print("inTestStr(Val(2), valMap):") inTestStr(Val(2), valMap) which gives: inTestStr(Val(2), valMap): False False False True False False What is wrong and why doesn't in operator work as expected? Continue reading...