1

For two dictionaries d1 and d2 defined as

d1 = {'foo':123, 'bar':789}
d2 = {'bar':789, 'foo':123}

The order of the keys is preserved in Python 3.6+. This is evident when we loop through the dictionary and print the items.

>>> for x in d1.items():
...     print(x)
...
('foo', 123)
('bar', 789)


>>> for x in d2.items():
...     print(x)
...
('bar', 789)
('foo', 123)

Why does Python still consider d1 and d2 to be equal?

>>> d1 == d2
True
Adarsh Chavakula
  • 1,509
  • 19
  • 28
  • 2
    For backwards compatibility, among other things. – Mad Physicist Nov 20 '19 at 18:30
  • 4
    Dictionaries aren't semantically ordered data structures, *even if they retain insertion order*. If you want a semantically ordered dictionary, use `OrderedDict` - `OrderedDict([("foo", 123), ("bar", 789)]) != OrderedDict([("bar", 789), ("foo", 123)])`. – jonrsharpe Nov 20 '19 at 18:30

2 Answers2

7

Dictionaries are hash tables, order is not supposed to matter. In python 3.6+ dictionaries are in insertion order but that is just how they are implemented. Order doesn't matter for equality. If you want order to matter in equality use an OrderedDict.

from collections import OrderedDict

d1 = OrderedDict({'foo':123, 'bar':789})
d2 = OrderedDict({'bar':789, 'foo':123})

print(d1 == d2) # False
  • In fact until Python 3.5, order of insertion was not maintained for `dicts`.. The fact that order of insertion is maintained can again change in any future version of Python – Vishal Nov 20 '19 at 18:32
  • 1
    True though the odds of them doing that are slim since it would not be backwards compatibable. In 3.5 it was a implementation detail, in 3.7 it was official. – Error - Syntactical Remorse Nov 20 '19 at 18:35
  • 1
    Yes - as of Python-3.7, it is [guaranteed by the language](https://stackoverflow.com/a/39980744/984421) that `dict` maintains insertion order. – ekhumoro Nov 20 '19 at 18:42
  • 1
    @Error-SyntacticalRemorse It was an implementation detail in 3.6, not 3.5. – blhsing Nov 20 '19 at 18:45
2

Dictionaries were unordered up until Python 3.6. Therefore the only sensible way to test for equality was to ignore the order. When Python 3.6 ordered dictionaries this was an implementation detail. Since Python 3.7 the insertion order can be relied upon. But changing the behavior to only consider dictionaries only equal if the keys are in the same order would break a whole lot of code. And quite frankly I think it is more useful to compare dictionaries without taking the ordering into account.

Pyfisch
  • 1,752
  • 1
  • 17
  • 29