Python
dictionary
keys
values
order

Python dictionary are keys and values always the same order?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

In Python 3.7+, dictionaries maintain insertion order as a language guarantee. Calling dict.keys(), dict.values(), and dict.items() always returns elements in the same insertion order. In Python 3.6, CPython's dict implementation preserved insertion order as an implementation detail (not a language guarantee). In Python 2 and Python 3.0-3.5, dictionaries had no guaranteed order.

Insertion Order Guarantee (Python 3.7+)

python
1d = {'b': 2, 'a': 1, 'c': 3}
2
3print(list(d.keys()))    # ['b', 'a', 'c']
4print(list(d.values()))  # [2, 1, 3]
5print(list(d.items()))   # [('b', 2), ('a', 1), ('c', 3)]

Keys and values are always in the same order — the order in which they were inserted. The i-th key corresponds to the i-th value:

python
1keys = list(d.keys())
2values = list(d.values())
3
4for i in range(len(d)):
5    assert d[keys[i]] == values[i]  # Always true

How Order Is Maintained

When you insert a key-value pair, it goes to the end. When you update an existing key, the order does not change — the key stays in its original position:

python
1d = {'x': 1, 'y': 2, 'z': 3}
2
3d['y'] = 99  # Update existing key — order preserved
4print(list(d.keys()))  # ['x', 'y', 'z'] — same order
5
6d['a'] = 4  # New key — goes to end
7print(list(d.keys()))  # ['x', 'y', 'z', 'a']

Deleting a key and re-inserting it places it at the end:

python
1d = {'x': 1, 'y': 2, 'z': 3}
2del d['y']
3d['y'] = 2
4print(list(d.keys()))  # ['x', 'z', 'y'] — 'y' moved to end

Python Version History

Python VersionDict Order
2.xNo guaranteed order
3.0 - 3.5No guaranteed order
3.6Insertion order (CPython implementation detail)
3.7+Insertion order (language specification)

In Python 2, if you needed ordered keys, you had to use collections.OrderedDict.

Zipping Keys and Values Is Safe

Since keys and values share the same order, you can safely zip them:

python
1d = {'name': 'Alice', 'age': 30, 'city': 'NYC'}
2
3# These are equivalent:
4pairs_from_items = list(d.items())
5pairs_from_zip = list(zip(d.keys(), d.values()))
6
7assert pairs_from_items == pairs_from_zip  # True

OrderedDict vs dict

collections.OrderedDict still exists but is mostly redundant since Python 3.7. It has a few extra features:

python
1from collections import OrderedDict
2
3od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
4
5# move_to_end — not available on regular dict
6od.move_to_end('a')       # Move 'a' to end
7print(list(od.keys()))    # ['b', 'c', 'a']
8
9od.move_to_end('c', last=False)  # Move 'c' to beginning
10print(list(od.keys()))    # ['c', 'b', 'a']
11
12# Equality considers order for OrderedDict
13od1 = OrderedDict([('a', 1), ('b', 2)])
14od2 = OrderedDict([('b', 2), ('a', 1)])
15print(od1 == od2)  # False — different order
16
17# Regular dict ignores order in equality
18d1 = {'a': 1, 'b': 2}
19d2 = {'b': 2, 'a': 1}
20print(d1 == d2)  # True — same keys and values
Featuredict (3.7+)OrderedDict
Insertion orderYesYes
move_to_end()NoYes
Order-sensitive equalityNoYes
Memory usageLessMore
PerformanceFasterSlightly slower

Sorting a Dictionary

Since dicts maintain order, you can create sorted versions:

python
1d = {'banana': 3, 'apple': 1, 'cherry': 2}
2
3# Sort by key
4sorted_by_key = dict(sorted(d.items()))
5print(sorted_by_key)  # {'apple': 1, 'banana': 3, 'cherry': 2}
6
7# Sort by value
8sorted_by_value = dict(sorted(d.items(), key=lambda x: x[1]))
9print(sorted_by_value)  # {'apple': 1, 'cherry': 2, 'banana': 3}
10
11# Sort by value descending
12sorted_desc = dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
13print(sorted_desc)  # {'banana': 3, 'cherry': 2, 'apple': 1}

Iterating in Reverse Order

python
1d = {'a': 1, 'b': 2, 'c': 3}
2
3# Python 3.8+: reversed() works on dict views
4for key in reversed(d):
5    print(key, d[key])
6# c 3
7# b 2
8# a 1
9
10# For items
11for key, value in reversed(d.items()):
12    print(key, value)

Common Pitfalls

  • Python version assumptions: Code relying on dict order will break on Python 3.5 or earlier. If supporting old versions, use OrderedDict or sort explicitly.
  • Equality ignores order: {'a': 1, 'b': 2} == {'b': 2, 'a': 1} is True for regular dicts. If order matters for comparison, use OrderedDict or compare list(d.items()).
  • JSON round-trip: json.loads(json.dumps(d)) preserves order in CPython, but the JSON specification does not guarantee object key order. Some JSON parsers may reorder keys.
  • Dict comprehension order: {k: v for k, v in iterable} preserves the iteration order of the iterable, which is guaranteed in Python 3.7+.
  • Concurrent modification: Adding or deleting keys while iterating raises RuntimeError. Collect keys to delete first, then delete after the loop.

Summary

  • Python 3.7+ guarantees that dict.keys(), dict.values(), and dict.items() maintain insertion order
  • The i-th key always corresponds to the i-th value
  • Updating an existing key does not change its position; deleting and re-inserting moves it to the end
  • OrderedDict adds move_to_end() and order-sensitive equality, but regular dict is sufficient for most use cases
  • Dict equality ignores order: {'a': 1, 'b': 2} == {'b': 2, 'a': 1} is True

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.