Dictionaries in Python are powerful, but they do not always come in the order you need. Whether you are ranking scores, organizing names alphabetically, or processing API responses, knowing how to python sort dictionary is a skill you will use constantly. Starting in Python 3.7, dictionaries maintain insertion order, which means once you sort and rebuild one, that order sticks.
This guide covers every practical way to sort a dictionary — by key, by value, ascending, descending, and even through nested structures — with working code and clear outputs at every step.
Before writing any code, it helps to understand what "sorting a dictionary" actually produces. Dictionaries themselves do not have a sort() method the way lists do. Instead, you use sorted() to produce a sorted sequence of key-value pairs, then optionally rebuild a new dictionary from that sequence using dict().
This distinction matters: sorted() always returns a list, not a dictionary. To get a sorted dictionary back, you wrap the result in dict().
scores = {"charlie": 88, "alice": 95, "bob": 72}
# sorted() on a dict iterates over keys by default
sorted_keys = sorted(scores)
print(sorted_keys)
['alice', 'bob', 'charlie']
That gives you a sorted list of keys. To get a proper sorted dictionary, you need to reconstruct it — which you will see throughout this guide.
Sorting a dictionary by its keys is the simplest case. You pass the dictionary directly to sorted(), which iterates over the keys. Then you zip the sorted keys back with their values using a dictionary comprehension or dict().
inventory = {"mango": 30, "apple": 85, "banana": 50, "grape": 20}
sorted_inventory = dict(sorted(inventory.items()))
print(sorted_inventory)
{'apple': 85, 'banana': 50, 'grape': 20, 'mango': 30}
The key call here is inventory.items(), which returns pairs like ('mango', 30). When you pass those pairs to sorted(), it compares the first element of each pair — the key — alphabetically. Wrapping the result in dict() gives you a proper python sorted dictionary.
To reverse the alphabetical order, pass reverse=True:
sorted_inventory_desc = dict(sorted(inventory.items(), reverse=True))
print(sorted_inventory_desc)
{'mango': 30, 'grape': 20, 'banana': 50, 'apple': 85}
This is all you need for alphabetical or reverse-alphabetical key sorting. No imports required.
Sorting by value is where most developers need a little extra help. By default, sorted() compares the first element in each tuple — the key. To sort by value instead, you tell sorted() which element to use as the comparison basis. You do this with the key parameter.
The most common way is a lambda function that pulls the second element (index 1) from each pair:
exam_scores = {"diana": 74, "evan": 91, "fiona": 63, "george": 88}
sorted_by_value = dict(sorted(exam_scores.items(), key=lambda item: item[1]))
print(sorted_by_value)
{'fiona': 63, 'diana': 74, 'george': 88, 'evan': 91}
The lambda lambda item: item[1] receives each (key, value) tuple and returns just the value. sorted() uses those returned values to rank the pairs from lowest to highest. The result is a python sort dict by value in ascending order.
To sort from highest to lowest — say, for a leaderboard:
leaderboard = dict(sorted(exam_scores.items(), key=lambda item: item[1], reverse=True))
print(leaderboard)
{'evan': 91, 'george': 88, 'diana': 74, 'fiona': 63}
Python's operator module provides itemgetter, which does the same job as the lambda above but is slightly faster and more readable once you know it. It is worth knowing because you will see it in real codebases.
from operator import itemgetter
product_prices = {"keyboard": 45.99, "monitor": 299.99, "mouse": 25.49, "headset": 79.99}
sorted_products = dict(sorted(product_prices.items(), key=itemgetter(1)))
print(sorted_products)
{'mouse': 25.49, 'keyboard': 45.99, 'headset': 79.99, 'monitor': 299.99}
itemgetter(1) is a callable that, when given a tuple, returns the item at index 1. It is equivalent to lambda x: x[1] but avoids the overhead of creating a new function object each time it is called. For small dictionaries the difference is invisible, but it is a clean habit.
Sometimes alphabetical or numeric order is not what you want. You might need to sort dictionary keys by their character length, or by some computed property. The key parameter handles this too.
words = {"elephant": 3, "cat": 1, "butterfly": 5, "dog": 2, "ant": 4}
# Sort by length of the key string
sorted_by_key_length = dict(sorted(words.items(), key=lambda item: len(item[0])))
print(sorted_by_key_length)
{'cat': 1, 'dog': 2, 'ant': 4, 'elephant': 3, 'butterfly': 5}
The lambda lambda item: len(item[0]) extracts the key (item[0]) and returns its length. Keys with fewer characters appear first. This shows how flexible the key parameter really is — you can sort by anything you can express as a function.
You can also sort by multiple criteria at once by returning a tuple from the key function. For example, sort by value first, then alphabetically by key to break ties:
tied_scores = {"zara": 80, "alice": 80, "mike": 75, "nina": 75}
sorted_multi = dict(sorted(tied_scores.items(), key=lambda item: (item[1], item[0])))
print(sorted_multi)
{'mike': 75, 'nina': 75, 'alice': 80, 'zara': 80}
Python compares tuples element by element, so (75, 'mike') comes before (75, 'nina') because 'mike' < 'nina' alphabetically.
Real-world data often has nested dictionaries — think of user records, product catalogs, or JSON from an API. Sorting a python sort nested dict requires reaching inside the nested structure with your key function.
Suppose you have a dictionary of employees where each value is itself a dictionary:
employees = {
"emp_3": {"name": "Carlos", "salary": 72000, "age": 34},
"emp_1": {"name": "Amara", "salary": 95000, "age": 29},
"emp_4": {"name": "Derek", "salary": 61000, "age": 41},
"emp_2": {"name": "Bianca", "salary": 83000, "age": 37},
}
# Sort by salary (nested value)
sorted_by_salary = dict(sorted(employees.items(), key=lambda item: item[1]["salary"]))
for emp_id, details in sorted_by_salary.items():
print(f"{emp_id}: {details['name']} — ${details['salary']}")
emp_4: Derek — $61000
emp_3: Carlos — $72000
emp_2: Bianca — $83000
emp_1: Amara — $95000
The lambda lambda item: item[1]["salary"] navigates into the nested dictionary to retrieve the salary value. You could swap "salary" for "age" or "name" to sort by any field. This pattern works for any depth of nesting as long as the keys exist.
Sometimes you do not need a dictionary back — you just need an ordered list of pairs to iterate over, display, or pass to another function. In that case, skip the dict() wrapping entirely.
city_populations = {
"Tokyo": 13960000,
"Delhi": 16787941,
"Shanghai": 24870895,
"São Paulo": 12325232,
"Mumbai": 12478447,
}
sorted_cities = sorted(city_populations.items(), key=lambda item: item[1], reverse=True)
for city, population in sorted_cities:
print(f"{city}: {population:,}")
Shanghai: 24,870,895
Delhi: 16,787,941
Mumbai: 12,478,447
São Paulo: 12,325,232
Tokyo: 13,960,000
city_populations.items() returns dict_items — a view of all key-value pairs. Passing that directly to sorted() gives you a list of tuples in your chosen order without rebuilding a dictionary. This is efficient when you just need to loop through results ranked by value.
Dictionary comprehensions are another clean way to rebuild a sorted dictionary. They read naturally and give you the chance to transform values at the same time as sorting.
temperatures = {"Oslo": -3, "Nairobi": 28, "Reykjavik": -8, "Bangkok": 35, "London": 12}
# Sort by temperature, convert to Fahrenheit in the same step
sorted_fahrenheit = {
city: round(temp * 9/5 + 32, 1)
for city, temp in sorted(temperatures.items(), key=lambda item: item[1])
}
print(sorted_fahrenheit)
{'Reykjavik': 17.6, 'Oslo': 26.6, 'London': 53.6, 'Nairobi': 82.4, 'Bangkok': 95.0}
The comprehension iterates over the already-sorted pairs and applies the Celsius-to-Fahrenheit formula to each value simultaneously. You get a sorted dictionary with transformed values in a single readable expression.
This final example brings together key sorting, value sorting, nested dict sorting, and custom multi-key sorting into one self-contained script. Run it directly — no extra installation needed.
from operator import itemgetter
# --- Dataset: online course catalog ---
courses = {
"python_basics": {"title": "Python Basics", "enrolled": 4320, "rating": 4.8},
"data_science_101": {"title": "Data Science 101", "enrolled": 2875, "rating": 4.6},
"web_dev_bootcamp": {"title": "Web Dev Bootcamp", "enrolled": 5100, "rating": 4.7},
"ml_fundamentals": {"title": "ML Fundamentals", "enrolled": 3640, "rating": 4.9},
"api_design": {"title": "API Design Patterns", "enrolled": 1980, "rating": 4.5},
}
print("=== Sorted by Course ID (Key) ===")
by_key = dict(sorted(courses.items()))
for cid in by_key:
print(f" {cid}")
print("\n=== Sorted by Enrollment (Value, Descending) ===")
by_enrollment = dict(sorted(courses.items(), key=lambda x: x[1]["enrolled"], reverse=True))
for cid, info in by_enrollment.items():
print(f" {info['title']}: {info['enrolled']:,} students")
print("\n=== Sorted by Rating, then Title (Multi-key) ===")
by_rating_title = dict(
sorted(courses.items(), key=lambda x: (-x[1]["rating"], x[1]["title"]))
)
for cid, info in by_rating_title.items():
print(f" {info['rating']} ⭐ {info['title']}")
print("\n=== Top 3 Courses by Enrollment ===")
top3 = dict(
sorted(courses.items(), key=itemgetter(1), reverse=False)
)
top3_by_enrolled = sorted(courses.items(), key=lambda x: x[1]["enrolled"], reverse=True)[:3]
for rank, (cid, info) in enumerate(top3_by_enrolled, start=1):
print(f" #{rank} {info['title']} ({info['enrolled']:,} enrolled, {info['rating']} stars)")
=== Sorted by Course ID (Key) ===
api_design
data_science_101
ml_fundamentals
python_basics
web_dev_bootcamp
=== Sorted by Enrollment (Value, Descending) ===
Web Dev Bootcamp: 5,100 students
Python Basics: 4,320 students
ML Fundamentals: 3,640 students
Data Science 101: 2,875 students
API Design Patterns: 1,980 students
=== Sorted by Rating, then Title (Multi-key) ===
4.9 ⭐ ML Fundamentals
4.8 ⭐ Python Basics
4.7 ⭐ Web Dev Bootcamp
4.6 ⭐ Data Science 101
4.5 ⭐ API Design Patterns
=== Top 3 Courses by Enrollment ===
#1 Web Dev Bootcamp (5,100 enrolled, 4.7 stars)
#2 Python Basics (4,320 enrolled, 4.8 stars)
#3 ML Fundamentals (3,640 enrolled, 4.9 stars)
The script demonstrates four distinct sorting strategies on the same nested dictionary: alphabetical key sort, descending enrollment sort using a nested value, multi-key sort with a negated rating to flip only one dimension, and a sliced top-3 list. All patterns follow the same core structure — sorted(dict.items(), key=...) — and each builds naturally on the fundamentals covered in this guide.