sorted()
documentation (emphasis mine):
The built-in sorted() function is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal [...]
In the code below, keys 8
and 16
have the same value, that is they would compare equal by the key=lambda x: d[x]
:
d = {8: 0, 16: 0, 'a': 1}
for i in range(200):
print(sorted(d, key=lambda x: d[x]))
# Prints always the same
# [8, 16, 'a']
# [8, 16, 'a']
# [8, 16, 'a']
# ......
Now lets try a small modification to the dictionary:
Example 1:
for i in range(10):
if i == 5:
del d[8]
del d[16]
d.update({16: 0})
d.update({8: 0})
print(sorted(d, key=lambda x: d[x]))
# Prints:
# [8, 16, 'a']
# [8, 16, 'a']
# [8, 16, 'a']
# [8, 16, 'a']
# [8, 16, 'a']
# [16, 8, 'a'] <----- it changed the order
# [16, 8, 'a']
# [16, 8, 'a']
# [16, 8, 'a']
# [16, 8, 'a']
id(d) remains the same. Also the contents remain the same. What changes is the order of key insertion.
Note:
Those keys were chosen so that they cause hash collisions:
whether 8 occupies a location or 16 is determined by which one arrived at the party first
Example 2:
d = {8: 0, 16: 0, 'a': 1}
c = {16: 0, 8: 0, 'a': 1}
print(sorted(d, key=lambda x: d[x]))
print(sorted(c, key=lambda x: d[x]))
I know that d
and c
are different objects here:
id(d) # 140067442777736
id(c) # 140067442811016
But I would expect that sorted()
treats objects that are d == c
the exact same way.
Example 3: A different example would be the following:
d = {'a': 0, 'b': 0, 'c': 0, 'd': 1}
print(sorted(d, key=lambda x: d[x]))
Running this on multiple different runs (not with a for
loop) would give a different order each time.
Note: That's assuming you use Python 3.3 or higher and your PYTHONHASHSEED=random
Question:
The order is not stable:
- for the same object that gets its order modified (example 1).
- for 2 objects that compare equal (example 2).
- for different runs of the exact same code (example 3).
Is the order instability mentioned above a bug or am I missing something? Do I misunderstand the documentation by expecting all 3 examples to have a stable order?