In Python 3.6 the implementatation of Python dictionaries was updated to make them more memory efficient. As a side-effect of this work, they now also retain insertion ordering.
This is still considered an implementation detail; future versions of Python may make it mandatory that dict
preserves order. See the What's New in Python 3.6 documentation:
The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).
If you are not using Python 3.6 (or newer), and see what appears to be an ordered sequence of keys, then you are looking at a coincidence. Integers used as keys often appear ordered, because their hash values have a direct relationship to the value of the integer (1 on 1 for all but one edge-case), causing them to be slotted in the same order if you have small integers:
>>> import sys
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=13, releaselevel='final', serial=0)
>>> {1: 'foo', 3: 'bar', 5: 'spam'}
{1: 'foo', 3: 'bar', 5: 'spam'}
See Why is the order in dictionaries and sets arbitrary? for a short overview of why this works.
Python 3.7 has elevated this implementation detail to be a Python language specification. This means all compliant implementations of the language must preserve insertion order in dictionaries.