Do Python dict literals and dict(list of pairs) keep their key order?

Question:

Do dict literals keep the order of their keys, in Python 3.7+? For example, is it guaranteed that {1: "one", 2: "two"} will always have its keys ordered this way (1, then 2) when iterating over it? (There is a thread in the Python mailing list with a similar subject, but it goes in all directions and I couldn’t find an answer.)

Similarly, is a dictionary like dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) ordered like in the list?

The same question is true for other naturally ordered constructions, like dict comprehension and dict(sape=4139, guido=4127, jack=4098).

PS: it is documented that dictionaries preserve insertion order. This question thus essentially asks: is it guaranteed that data is inserted in the order of a dict literal, of the list given to dict(), etc.

Asked By: Eric O Lebigot

||

Answers:

Yes, any method of constructing a dict preserves insertion order, in Python 3.7+.


For literal key-value pairs, see the documentation:

If a comma-separated sequence of key/datum pairs is given, they are evaluated from left to right to define the entries of the dictionary

For comprehensions, from the same source:

When the comprehension is run, the resulting key and value elements are inserted in the new dictionary in the order they are produced.

Lastly, the dict initializer works by iterating over its argument and keyword arguments, and inserting each in order, similar to this:

def __init__(self, mapping_or_iterable, **kwargs):
    if hasattr(mapping_or_iterable, "items"):  # It's a mapping
        for k, v in mapping_or_iterable.items():
            self[k] = v
    else:  # It's an iterable of key-value pairs
        for k, v in mapping_or_iterable:
            self[k] = v

    for k, v in kwargs.items():
        self[k] = v

[This is based on the source code, but glossing over a lot of unimportant details, e.g. that dict_init is just a wrapper on dict_update_common.]

This, combined with the fact that keyword arguments pass a dictionary in the same order since Python 3.6, makes dict(x=…, y=…) preserve the order of the variables.

Answered By: wjandrea
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.