Sign in to your Python Morsels account to save your screencast settings.
Don't have an account yet? Sign up here.
Python's dictionaries are ordered.
If we create a dictionary, the keys will remain in the same order as they started with:
>>> fruit_counts = {"apple": 2, "banana": 4, "mango": 1}
>>> fruit_counts
{'apple': 2, 'banana': 4, 'mango': 1}
If we loop over this dictionary, we'll see apple
, and then banana
, and then mango
, because that was the order of the keys when we made the dictionary:
>>> for fruit in fruit_counts:
... print(fruit)
...
apple
banana
mango
Now, you may have heard that dictionaries are unordered in Python. That used to be true. Before Python 3.6, dictionaries were unordered.
Here we've dusted off an old Python 2.7 interpreter:
$ python2
Python 2.7.18 (default, Aug 23 2022, 17:18:36)
[GCC 11.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
If we create a dictionary in Python 2, the order of the keys might shuffle around:
$ python2
>>> fruit_counts = {"apple": 2, "banana": 4, "mango": 1}
>>> for fruit in fruit_counts:
... print fruit
...
mango
apple
banana
Our keys started as apple
, banana
, mango
, but we ended up with mango
, apple
, banana
.
If we added another key to this dictionary, we would see that the order may sometimes shuffle around even further:
>>> fruit_counts['orange'] = 3
>>> fruit_counts
{'orange': 3, 'mango': 1, 'apple': 2, 'banana': 4}
Dictionaries in Python didn't used to be ordered, but they are now. In Python 3.6 dictionaries, became unofficially ordered. In Python 3.7, this became an official feature that we can rely on: dictionaries in Python maintain their order!
Keep in mind that dictionaries are ordered, but they're not sorted. Specifically, dictionaries maintain the insertion order of their keys.
If we add a new key to a dictionary, it will always add at the end:
>>> fruit_counts = {"apple": 2, "banana": 4, "mango": 1}
>>> fruit_counts["lemon"] = 3
>>> fruit_counts
{'apple': 2, 'banana': 4, 'mango': 1, 'lemon': 3}
But if we update the value of an existing key, that key will remain in its original position:
>>> fruit_counts = {"apple": 2, "banana": 4, "mango": 1, 'lemon': 3}
>>> fruit_counts["apple"] = 5
>>> fruit_counts
{'apple': 5, 'banana': 4, 'mango': 1, 'lemon': 3}
Though, if we removed the key first and then added it again, it would move to the end of the dictionary:
>>> fruit_counts = {"apple": 2, "banana": 4, "mango": 1, 'lemon': 3}
>>> del fruit_counts["apple"]
>>> fruit_counts["apple"] = 2
>>> fruit_counts
{'banana': 4, 'mango': 1, 'lemon': 3, 'apple': 2}
Dictionary maintain their items based on the insertion order of the keys.
Dictionaries are also reversible now.
So if we wanted to loop over a dictionary with the most recently added keys first, we could use the built-in reversed
function in Python:
>>> fruit_counts = {"apple": 2, "banana": 4, "mango": 1}
>>> for fruit, count in reversed(fruit_counts.items()):
... print(count, fruit)
...
1 mango
4 banana
2 apple
While dictionaries are ordered, and they are reversible, they're not sequences.
Unlike lists, dictionaries don't have any notion of indexes. Meaning, for example, there's no easy way to look up the middle key within a dictionary.
However, we could rely on the iterator protocol to get the first key or get the last key in a dictionary:
>>> first_fruit = next(iter(fruit_counts))
>>> last_fruit = next(reversed(fruit_counts))
>>> first_fruit
'apple'
>>> last_fruit
'mango'
Also note that it's a little bit unusual to heavily rely on the order of dictionaries.
Whenever you find yourself looping over a dictionary, you might want to ask whether you actually need a dictionary or whether a different data structure (such as a list of tuples) might have worked just as well.
>>> fruit_counts = [("apple", 2), ("banana", 4), ("mango", 1), ("pineapple", 3)]
>>> for fruit, count in fruit_counts:
... print(count, fruit)
...
2 apple
4 banana
1 mango
3 pineapple
Dictionaries in Python maintain the insertion order of their keys.
Meaning when you add a new key to a dictionary, it adds to the end. But if you update an existing key, it'll stay in the same location.
This is a somewhat uncommon feature to rely on, though it can sometimes be handy to use the same data structure for both key lookups and iteration.
Need to fill-in gaps in your Python skills?
Sign up for my Python newsletter where I share one of my favorite Python tips every week.
Sign in to your Python Morsels account to track your progress.
Don't have an account yet? Sign up here.