Live data from Hacker News

Python dicts are now ordered

softwaremaniacs.org

111–120 of 457 posts

Re: Python dicts are now ordered

#112

Earlier quoted context omitted.

It doesn’t break existing code. Code written for Python 3.7 might break on older versions of Python

If you know you're supporting old code, use OrderedDict. you arguably ought to anyway, for explicitness.

OrderedDict is slow and expensive though: it maintains ordering through a doubly linked list.

It has useful features for manipulating ordering but while I've regularly needed had use for maintaining insertion ordering I can't remember ever needing to move items around within a map.

Re: Python dicts are now ordered

#114
post #4

Earlier quoted context omitted.

Is the ordering there at least fixed, or can it vary from run to run even on the same data, or between implementations or versions of the same implementation? EDIT: to clarify, I was asking about JavaScript there.

If the ordering is determined by a hash function and it's always the same it is likely a defect in the implementation, because keys can be easily chosen to cause massive performance degredation; essentially a DoS attack. That's why many dynamic languages these days use things like siphash with a random key.

I'll argue that having the order depend on the hash function, rather than insertion order, is the problem. It's bad to have unnecessary nondeterminism in software. It makes testing and reproducing bugs unnecessarily difficult.

Re: Python dicts are now ordered

#115
post #10

This is a solid argument for why you should have more datatypes available to you. If your program relies on an insertion order, say so. If anyone ever moves to another implementation, they will thank you for it.

Ordered dictionaries already existed as a separate type. Much of the gain was in the use of dicts for core language features.

In particular, Python 3.6 guarantees that the order in which class attributes are defined is preserved, and that functions which take variadic keyword arguments receive them in the order in which they were passed. It permits other implementations to use types other than dict to accomplish that.

Dataclasses make use of ordering of dictionaries in a subtle way. If you write:

  class Foo:
      bar: int
      baz: str
Then Foo.__annotations__ is a dictionary {'bar': int, 'baz': str}. The @dataclass decorator transforms that into standard boilerplate, and it needs to know the order to do that.

Re: Python dicts are now ordered

#116
post #64

Earlier quoted context omitted.

CPython is mot the only Python. Portability is an issue also.

Portability isn't affected; if they claim compatibility with python3.7, then they claim their dicts have insertion-ordered keys. If they claim compatibility with only up to python3.6, they can have whatever order they choose. The only issue with portability is that I think the main reason it was made a gaurantee is that cpython found the new, presumably optimized, implementation came with insertion order for free, so…

That also goes both way: Pypy defaulted to ordered dicts a few years before cpython did.

Re: Python dicts are now ordered

#117
post #84

Great decision IMO. I remember maintaining a bunch of Python code that we supported on both OSX and Windows. Out of all the platform-specific bugs we had (where it worked on one OS and not the other), one of the most common causes was code that relied on a certain key order. And we knew that relying on key order was bad, we're supposed to use things like OrderedDict, blah blah blah. It was still a really easy mistake…

The Go designers went the other way (as they often do): > When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Actually it is not only "not guaranteed to be the same", the runtime actively makes sure that the iteration order is actually different so you don't even start to rely on it...

That’s fairly common, as it is protection against denial-of-service attacks that use hash collisions to make code perform poorly (https://events.ccc.de/2011/12/28/crypto-talk-at-28c3-effecti...)

If I read https://lwn.net/Articles/474912/ correctly, Perl fixed that in 2003. C#, Java and Swift do it, too. As does (or, reading this, did?) Python (https://bugs.python.org/issue13703)

Re: Python dicts are now ordered

#118
post #84

Earlier quoted context omitted.

The Go designers went the other way (as they often do): > When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Actually it is not only "not guaranteed to be the same", the runtime actively makes sure that the iteration order is actually different so you don't even start to rely on it...

That seems like it would be a performance hit to actively make it different? That seems like a very weird and strange design decision if true

> That seems like it would be a performance hit to actively make it different

Not really. I don't know the go implementation but you can get this behaviour by adding an arbitrary "startup defined" seed to your hash function and that does the trick.

It also gives the benefit of making hash table attacks harder.

Re: Python dicts are now ordered

#119

question: does the following expression still evaluate to True with ordered dicts? {'a':1, 'b':2} == {'b':2, 'a':1}

nevermind, i thought this was a future change, but it's already live. i've been using 3.7.4, and can confirm that two dictionaries with equivalent key,value pairs, even if inserted in a different order, are considered abstractly equal.

this coincidentally came up for me this morning on a small interview challenge: https://dev.to/candidateplanet/comment/l8o2

Re: Python dicts are now ordered

#120

I'd love to know more about where an ordered dict comes in handy. Anyone have use cases? Otherwise, guaranteeing this behavior just seems ‾\_(ツ)_/‾ If this is useful, I wonder if an ordered set is useful.

> If this is useful, I wonder if an ordered set is useful.

An ordered set is a unique list. It's useful. However it's not present in Python, dicts and sets have separate implementations and sets were not moved over to the ordered implementation (because the ordering was initially a side-effect of a change in implementation which was not considered useful or advantageous for sets).

Post reply on HN