5

Everywhere I search, they say python dictionary's doesn't have any order. When I run code 1 each time shows a different output (random order). But when I run code 2 it always shows the same sorted output. Why is the dictionary ordered in the second snippet?

   #code 1

    d = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
    for a, b in d.items():
        print(a, b)
   #code 2 

    d = {1: 10, 2: 20, 3: 30, 4: 40}
    for a, b in d.items():
        print(a, b)

Outputs

code 1:

four 4
two 2
three 3
one 1

code 1 again:

three 3
one 1
two 2
four 4

code 2 (always):

1 10
2 20
3 30
4 40
limoragni
  • 2,716
  • 2
  • 32
  • 50
lordkian
  • 95
  • 7

2 Answers2

13

It's related to how hash randomisation is applied. Quoting docs (emphasis mine):

By default, the __hash__() values of str, bytes and datetime objects are “salted” with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python.

For each subsequent run, your strings (keys in snippet 1) are hashed with different salt value - therefore hash value is also changed. Hash values determine ordering.

For int type, hash function never changes - in fact hash is always equal to integer value.

assert hash(42) == 42

If hashing function never changes, there is no change in ordering in subsequent runs.

For details in how Python dictionaries are implemented, you may refer to How are Python's Built In Dictionaries Implemented.

Community
  • 1
  • 1
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
  • 6
    Hash is not always identity on integers. `-1` hashes to `-2` and hash of really big integers has to come down too e.g. `hash(10**20)` – wim Dec 28 '15 at 19:57
0

Not anymore: from Python 3.6 onwards, the standard dict type maintains insertion order by default, see the What's New in Python 3.6 documentation here.

Python 3.7 elevated this implementation detail to a language specification, so it is now mandatory that dict preserves order Python 3.7+

(via @Martijn Pieters answer here, and the Python documentation here)

dumbledad
  • 16,305
  • 23
  • 120
  • 273