Rich Comparisons Gotcha

Rasmus Fogh rhf22 at mole.bio.cam.ac.uk
Tue Dec 9 06:50:22 EST 2008


Steven DAprano wrote:
> On Mon, 08 Dec 2008 14:24:59 +0000, Rasmus Fogh wrote:

snip

>> What might be a sensible behaviour (unlike your proposed wrapper)

Sorry
1) I was rude,
2) I thanked TJR for your wrapper class proposal in a later mail. It is
yours.

> What do you dislike about my wrapper class? Perhaps it is fixable.

I think it is a basic requirement for functioning lists that you get
>>> alist = [1,x]
>>> x in alist
True
>>> alist.remove(x)
>>> alist
[1] # unless of course x == 1, in which case the list is [x].

Your wrapper would not provide this behaviour. It is necessary to do
if x is y:
  return True
be it in the eq() function, or in the list implementation. Note that this
is the current python behaviour for nan in lists, whatever the mathematics
say.

>> would be the following:

>> def eq(x, y):
>>   if x is y:
>>     return True

> I've already mentioned NaNs. Sentinel values also sometimes need to
> compare not equal with themselves. Forcing them to compare equal will
> cause breakage.

The list.__contains__ method already checks 'x is y' before it checks 'x
== y'. I'd say that a list where my example above does not work is broken
already, but of course I do not want to break further code. Could you give
an example of this use of sentinel values?

>>   else:
>>     try:
>>       return (x == y)
>>     except Exception:
>>       return False

> Why False? Why not True? If an error occurs inside __eq__, how do you
> know that the correct result was False?

> class Broken(object):
>     def __eq__(self, other):
>         return Treu  # oops, raises NameError

In managing collections the purpose of eq would be to divide objects into
a small set that are all equal to each other, and a larger set that are
all unequal to all members of the first set. That requires default to
False. If you default to True then eq(aNumpyArray, x) would return True
for all x.

If an error occurs inside __eq__ it could be 1) because __eq__ is badly
written, or 2) because the type of y was not considered by the
implementers of x or is in some deep way incompatible with x. 1) I cannot
help, and for 2) I am simply saying that value semantics require an __eq__
that returns a truth value. In the absence of that I want identity
semantics.

Rasmus




More information about the Python-list mailing list