[Python-ideas] Fwd: Why do equality tests between OrderedDict keys/values views behave not as expected?
Guido van Rossum
guido at python.org
Sat Dec 19 11:22:35 EST 2015
On Sat, Dec 19, 2015 at 5:46 AM, Random832 <random832 at fastmail.com> wrote:
> Guido van Rossum writes:
> > The link between hashing and immutability is because objects whose
> > hash would change are common, e.g. lists, and using them as dict keys
> > would be very hard to debug for users most likely to make this
> > mistake. The issue is that the dict implementation makes it impossible
> > to find back keys whose hash has changed, other than by linear search,
> > which is unacceptable -- but that's exactly what users will try to
> > debug such issues, i.e., print the dict and notice that the missing
> > key is indeed present.
>
> Java doesn't seem to have this problem. Python uses dicts more
> heavily as part of its core architecture, sure, but those dicts
> use strings as their keys.
>
> > The consenting adults rule typically applies to things that are well
> > hidden or marked (e.g. using __dunder__ names).
>
> The ability to e.g. replace a class or module's functions, or
> values intended as constants, is not especially well-hidden.
>
> > There are plenty of things that Python could allow but doesn't, not
> > because they are hard to implement or would violate an invariant of
> > the interpreter, but because they could trip over naive users.
> >
> > Note that you are turning things upside down: the question "why aren't
> > all things hashable" came about because Andrew was considering making
> > a hash table of the values of a dict.
>
> Well, sure, but that's a reasonable way (if the ability to do so
> were present) to implement the operation being discussed under
> the performance constraints he specified.
>
> > But the real question here isn't "why aren't all things hashable" but
> > "why can't you put mutable values into a set". The answer to the
> > latter is because when we put a value into a container, and later the
> > value changes, we can't tell the container, so if the container has
> > any sort of lookup scheme other than linear search, it would lose
> > track of the value.
>
> Yes, but you're fine as long as the value doesn't change.
>
> What do you think about my __vhash__ idea? Someone would only
> make sets/dicts that use __vhash__ rather than __hash__ if they
> can guarantee the object won't change in the lifetime of its
> presence in the container (something that's no problem for the
> short-lived container that would be used for this operation)
>
You can solve this without adding warts to the language by using a wrapper
object.
> > Hashing comes into play because all of Python's common data structures
> > use hashing to optimize lookup -- but if we used a different data
> > structure, e.g. something based on sorting the keys, we'd still have
> > the mutability problem. And we'd have worse problems, because values
> > would have to be sortable, which is a stricter condition than being
> > immutable.
> >
> > In any case, you can't solve this problem by making all values
> > hashable.
>
> Sure I can.
>
> Normal dict values:
> def __eq__(self, b):
> return Counter(self) == Counter(b)
> #or e.g. Counter(map(self, make_vhash_key)) ...
>
> OrderedDict values:
> def __eq__(self, b):
> if isinstance(b, OrderedDict)
> return List(self) == List(b)
> else:
> return super().__eq__(b)
> # Yes, this isn't transitive, i.e. maybe:
> # a == c and b == c where a != b
> # but the same is true today for the dicts.
>
> >>> a = collections.OrderedDict(((1, 2), (3, 4)))
> >>> b = collections.OrderedDict(((3, 4), (1, 2)))
> >>> c = {1: 2, 3: 4}
> >>> a == c, b == c, a == b
> (True, True, False)
>
I don't see what that bit of code proves (or most other things you wrote
above).
--
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20151219/01f4ef28/attachment-0001.html>
More information about the Python-ideas
mailing list