Dominik Vilsmeier writes:

 > Well, the point is that this "except comparisons" is not quite true:
 > 
 >      >>> i = {'a': []}.items()
 >      >>> s = {('a', 1)}
 >      >>> i == s
 >      TypeError: unhashable type: 'list'
 > 
 > If passed a set as `other` operand, dict_items seems to decide to
 > convert itself to a set, for no obvious reasons since, as you
 > mentioned, it does know how to compare itself to another view
 > containing non-hashable values:

The obvious reason is that they didn't want to implement the
comparison if you didn't have to, the dict.items() view is a Set, so
the obvious implementation is s == set(i).

 > So if you're dealing with items views and want to compare them to a set
 > representing dict items, then you need an extra `try/except` in order to
 > handle non-hashable values in the items view.

Sounds like you have a change to propose here, then.  Put the
try/except in the __eq__ for the items view class when comparing
against a set.  I would expect it to be accepted, as comparing items
views is pretty expensive so the slight additional overhead would
likely be acceptable, and if you get the exception, you know the
equality comparison against a set is false since a set cannot contain
that element, so this possibility can't affect worst-case performance
by much, if at all.

 > Surely [dict.values equality comparison having object equality
 > semantics] must be a relic from pre-3.7 days where dicts were
 > unordered and hence order-based comparison wouldn't be possible
 > (though PEP 3106 describes an O(n*m) algorithm). However the
 > current behavior is unfortunate because it might trick users

You mean "users might trick themselves".  We provide documentation for
exactly this reason.

 > So why not make dict_values a Sequence, providing __getitem__ and
 > additionally order-based __eq__ comparison?

Besides making dict more complex, and possibly preventing future
improvements because of backward compatibility with this requirement,
dict comparisons and dict.keys comparisons are done with set
semantics.  So I would expect dict.values comparisons to have multiset
semantics, not sequence semantics.  I would feel very cheated when I
found out d1.values() == d2.values() had sequence equality semantics!

If you want sequence semantics for dict.values equality, I'm pretty
sure this DTRT:

    def sequence_equal(v1, v2):    # v1, v2 are dict.values objects
        return len(v1) == len(v2) and all(x == y for x, y in zip(v1, v2))

But I can't imagine wanting that.  The only time I ever care that
dicts are ordered is writing doctests, and then I'm very happy!  But I
can't recall ever wanting to write a doctest for equality on
dict.values.  Equality of the dict itself is always what I want.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XRCNTJEBU47PS57TGYQ7ODZUAK5MSQAR/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to