Is key order preserved in a Python dictionary?

Updated: February 12, 2024 By: Guest Contributor Post a comment

Introduction

In Python, a dictionary is a collection which is unordered, changeable, and indexed. Or, at least, that was the narrative until the later Python versions came along. Beginning with Python 3.7, dictionaries now maintain their insertion order by default. This feature has been backported to Python 3.6 as an implementation detail, but it’s in 3.7 where it’s officially part of the language specification. This tutorial will explore what this means for you as a Python programmer, including how it impacts the way you can work with dictionaries.

Early Python Dictionaries

Historically, dictionaries in Python were unordered. This means that before Python 3.6, there was no guarantee that keys would maintain their order of insertion, and iterating over a dictionary’s keys, values, or items would not necessarily follow the order in which they were added.

# Python 3.5 and earlier
my_dict = {'one': 1, 'two': 2, 'three': 3}
for key in my_dict:
    print(key)
# Output could vary

In Python 3.6+

Python 3.6 unintentionally introduced the preservation of insertion order in dictionaries as an implementation detail. However, it was made an official language feature in Python 3.7. This means that when you insert items into a dictionary, they will be stored in the order they were added. Subsequent Python versions have continued to uphold this behavior.

# Python 3.7 and later
my_dict = {'one': 1, 'two': 2, 'three': 3}
for key in my_dict:
    print(key)
# Output:
# one
# two
# three

Dictionaries with Ordered Keys: Advantages

Maintaining key order can be advantageous, especially when it comes to tasks such as serializing data (e.g., converting to JSON), where the order of elements can be significant. It also makes the code more predictable and easier to understand, as the data structure’s behavior aligns more closely with the developer’s intentions.

Examples and Use Cases

Let’s explore some examples and use cases that benefit from ordered dictionaries.

1. Iteration Order

# Basic usage
persons = {'Alice': 25, 'Bob': 30, 'Charlie': 35}
for name in persons:
    print(f'{name} is {persons[name]} years old.')

2. Data Serialization

# Serialization example
import json
persons_json = json.dumps(persons, indent=4)
print(persons_json)

3. Maintaining Order in Function Arguments

# Using **kwargs
def greeting(**kwargs):
    for key in kwargs:
        print(f'Hello, {kwargs[key]}!')</n
greeting(Alice='New York', Bob='London', Charlie='Berlin')

4. Advanced: Collections.OrderedDict

Before the change in dictionaries was made, if a Python developer needed to guarantee the order of elements within a dictionary, they would turn to OrderedDict from the collections module. This class maintains the order of keys as they were inserted.

from collections import OrderedDict

od = OrderedDict([('one', 1), ('two', 2), ('three', 3)])
for key in od:
    print(key)
# Output matches insertion order
# one
# two
# three

Although dict now maintains order by default, OrderedDict is still useful for operations that require the order of addition to be maintained, like reversing the order of elements, or when you need backwards compatibility with older versions of Python.

Comparison with Other Languages

Many modern programming languages guarantee an ordered collection type similar to Python’s ordered dictionaries. For example, JavaScript’s Map object maintains key insertion order. Understanding these similarities and differences can be important when moving between languages or working with systems that utilize multiple programming languages.

Conclusion

With the official adoption of insertion-order preservation in Python 3.7 dictionaries, Python took a significant step towards making its language more accessible and intuitive. This change enhances predictability when coding, making dictionaries not only a powerful data structure for key-value pairing but also for maintaining order where it matters. As Python continues to evolve, features like these demonstrate the language’s commitment to developer ease and practicality.