[Python-Dev] Guarantee ordered dict literals in v3.7?

Chris Angelico rosuav at gmail.com
Tue Dec 19 02:37:20 EST 2017


On Tue, Dec 19, 2017 at 6:09 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> I completely agree. We might argue that it was a mistake to sort dicts
> in the first place, or at least a mistake to *always* sort them without
> allowing the caller to provide a sort key. But what's done is done: the
> fact that dicts are sorted by pprint is not merely an implementation
> detail, but a documented behaviour.

Personally, I think it's a good default behaviour. Frequently you have
a dictionary that, in normal code, you look up by key rather than
iterating over; but for debugging, you print out everything. (Example:
HTTP request/response headers. In your code, you'll query the headers
dict for "content-type", but it's nice to be able to say "show me
every header".) Insertion order is meaningless, and it's nice to be
able to read them in some kind of sane order. Simply sorting the keys
in the default way is good enough for a LOT of use-cases.

> I'm not denying that sometimes it would be nice to see dicts in
> insertion order. Right now, those use-cases are handled by OrderedDict
> but in the future many of them will be taken over by regular dicts. So
> we have a conflict:
>
> - for some use-cases, insertion order is the "right" way for pprint
>   to display the dict;
>
> - but for others, sorting by keys is the "pretty" way for pprint to
>   display the dict;
>
> - and there's no way for pprint to know which is which just by
>   inspecting the dict.
>
> How to break this tie? Backwards compatibility trumps all. If we want
> to change the default behaviour of pprint, we need to go through a
> deprecation period.
>
> Or add a flag sorted=True, and let the caller decide.

Agreed, except for the last bit. I'd be inclined to kill two birds
with one stone: add a flag sort_key=DEFAULT or sort_key=IDENTITY,
which will sort the keys by themselves; you can provide a key function
to change the way they're sorted, or you can pass sort_key=None to get
them in insertion order.

>> I would think it was only the right choice in the first place in order (get
>> it?) to get a consistent representation, not because sorting was a good
>> thing per se.
>
> *shrug* That's arguable. As you said yourself, dicts were sorted by key
> to give a "pretty" representation. I'm not so sure that consistency is
> the justification. What does that even mean? If you print the same dict
> twice, with no modifications, it will print the same whether you sort
> first or not. If you print two different dicts, who is to say that they
> were constructed in the same order?

In old versions of Python, this code would always produce the same result:

d = {}
d["qwer"] = 1
d["asdf"] = 2
d["zxcv"] = 3
print(d)
import pprint; pprint.pprint(d)

Then along came hash randomization, and the output would change - but
pprint would still be consistent and tidy. Now we have insertion order
retained, and both the repr and the pprint are consistent. Both of
them are sane. They're just different sameness.

> But the point is moot: whatever the justification, the fact that pprint
> sorts dicts by key is the defined behaviour, and even if it was a
> mistake to guarantee it, we can't just change it without a deprecation
> period.

This is really the clincher. But IMO the current behaviour isn't
*just* for backcompat; it's good, useful behaviour as it is. I
wouldn't want to see it changed even _with_ deprecation.

ChrisA


More information about the Python-Dev mailing list