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.