On Tue, Jul 23, 2019 at 10:02:34PM -0400, Terry Reedy wrote:

[...]
> If one has not learned the default meaning of '==' in Python.  Perhaps 
> this should be given more emphasis in beginner courses.  "What does it 
> mean for two object to be 'equal'?"  It is not a trivial question.

No, it is not trivial, but the default meaning of equality in Python 
does not match the common idea that two things are equal if they are the 
same, equivalent, interchangeable, etc. By default, no two objects are 
ever equal, even if their values are equal. Equality only holds between 
an object and itself.

(In fairness, it is hard to think of another, more useful, definition of 
equality suitable as the default.)

In any case, the default semantics of equality inherited from object may 
explain the current behaviour, but that doesn't mean that the current 
behaviour is useful. When it is meaningful to say that "the value of 
these two distinct objects are equal", that is a strong hint that 
equality ought to be based on the value, rather than the identity, of 
the objects.


[...]
> Makes sense, up to here.

I'm glad to hear it, because I think that's a strong invariate: if the 
items are equal, so should the values be equal.

Beyond that, I'm not certain what is the right behaviour.



> >          # Fall back on value by value comparison?
> >          return list(self) == list(other)
> 
> This seems wrong.  Creating two lists raises the cost and the comparison 
> will depend on insertion order.

You're probably right. I did say that this was potentially expensive. We 
should be able to avoid the needless creation of two lists:

    return all(x==y for x, y in zip(self, other))

but that still leaves the insertion order problem.

How does this seem to you? Two dict.values objects are equal if:

- they are in fact the same object (identity test on the views);

- they are both views of the same dict (identity test on the dicts);

- they are views of distinct, but equal, dicts;

- or there is a 1:1 correspondence between values (possibly not 
  unique) in the two views.


The first three tests should be straight-forward. The last is likely be 
slow, but something like this ought to work:

    a = list(self)
    b = list(other)
    return len(a) == len(b) and all(a.count(x) == b.count(x) for x in a)


Given that we cannot rely on the values being hashable or even sortable, 
I don't know how to make it more efficient in the general case.



-- 
Steven
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/JD74V5OSJDY7BHJWLXVD5NKQ5EP75EGL/

Reply via email to