[issue21234] __contains__ and friends should check "is" for all elements first
Wolfgang Maier
report at bugs.python.org
Wed Apr 16 15:20:59 CEST 2014
Wolfgang Maier added the comment:
that clarifies things, thanks.
I would still not usually go that way though as it means defining __ne__ with no accompanying __eq__, which means that, in a simple case, you can't use == on instances of your class and, in the case that your class inherits __eq__ from a parent, that == and != give inconsistent answers.
A much simpler solution is to not use the x in y idiom if you know it is slowed down by expensive equality checks in the elements of y and you're only interested in the identity check.
Simply replace it with
any(element is x for element in y)
, which will run at decent speed.
A quick illustration:
class myObj(object):
def __eq__(self, other):
for i in range(10000): pass # simulate an expensive check
return False
l=[myObj() for x in range(10000)]
now compare:
>>> 1 in m # slowed down by myObj.__eq__
False
>>> any(e is 1 for e in m) # identity checks only
False
=> no class-level hacking required, but still a good performance gain.
Of course, if you really need bets performance with identity *and* equality checks, then your solution may make sense, but that looks like a pretty special requirement.
(and even then I would replace the ugly
not all(map(ne, repeat(obj), container)) # requires 2 imports to be so hard to read
with:
not all(element != obj for element in container)
)
----------
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue21234>
_______________________________________
More information about the Python-bugs-list
mailing list