Dictionaries are one of the most versatile and frequently used data structures in Python. On the flip side, they store data as key-value pairs, offering lightning-fast lookups, insertions, and deletions. On the flip side, because dictionaries were historically unordered collections (prior to Python 3.7), developers often face a common challenge: how to sort a dictionary by value rather than by key. Whether you are ranking user scores, organizing inventory by stock quantity, or analyzing word frequencies in a text corpus, mastering this technique is essential for effective data manipulation Easy to understand, harder to ignore..
Understanding Dictionary Order in Modern Python
Before diving into the sorting mechanics, it is crucial to understand how Python handles dictionary order today. Plus, this became a formal language specification in Python 3. On the flip side, 7, the insertion order of dictionaries is guaranteed to be preserved. Plus, 8**. Here's the thing — since **Python 3. Simply put, if you create a new dictionary with items inserted in a specific sequence, that sequence remains intact during iteration And that's really what it comes down to. Less friction, more output..
This behavior is the foundation of sorting dictionaries. We cannot "sort a dictionary in place" like a list using list.sort(). Instead, we must create a new dictionary (or an ordered collection of tuples) where the items are inserted in the desired sorted order Worth keeping that in mind..
The Core Mechanism: The sorted() Function
The built-in sorted() function is the primary tool for this task. Even so, it accepts an iterable and returns a new list containing the items in ascending order. The magic happens with the key parameter, which allows you to define a custom sorting criterion.
The moment you iterate over a dictionary directly (e.So naturally, g. , for item in my_dict), you get the keys. To sort by value, you need to iterate over the key-value pairs using the .items() method, which returns a view object yielding (key, value) tuples Worth knowing..
Basic Syntax Breakdown
sorted_items = sorted(my_dict.items(), key=lambda item: item[1])
Let's deconstruct this line:
my_dict.items(): Returns a view of(key, value)tuples. Even so, 2. Also,key=lambda item: item[1]: Thekeyargument expects a function that takes one argument (the tuple) and returns the value to compare.item[0]is the key;item[1]is the value. Thelambdafunction extracts the second element (the value) for comparison.- Return Value: A list of tuples, sorted by the dictionary values.
Step-by-Step Implementation Guide
Here is the standard workflow to transform an unsorted dictionary into a new dictionary ordered by values.
1. Define the Source Data
Imagine a dictionary representing the popularity of programming languages based on a hypothetical survey index.
language_popularity = {
'Python': 95,
'JavaScript': 88,
'Java': 82,
'C++': 78,
'Go': 72,
'Rust': 68
}
2. Sort Ascending (Low to High)
This is the default behavior of sorted() Not complicated — just consistent..
# Returns a list of tuples: [('Rust', 68), ('Go', 72), ..., ('Python', 95)]
sorted_ascending = sorted(language_popularity.items(), key=lambda x: x[1])
# Convert back to a dictionary (preserves order in Python 3.7+)
sorted_dict_asc = dict(sorted_ascending)
print(sorted_dict_asc)
# Output: {'Rust': 68, 'Go': 72, 'C++': 78, 'Java': 82, 'JavaScript': 88, 'Python': 95}
3. Sort Descending (High to Low)
For rankings, leaderboards, or "top N" lists, descending order is usually preferred. Add the reverse=True argument Not complicated — just consistent..
# Returns list of tuples: [('Python', 95), ('JavaScript', 88), ...]
sorted_descending = sorted(language_popularity.items(), key=lambda x: x[1], reverse=True)
sorted_dict_desc = dict(sorted_descending)
print(sorted_dict_desc)
# Output: {'Python': 95, 'JavaScript': 88, 'Java': 82, 'C++': 78, 'Go': 72, 'Rust': 68}
Advanced Sorting Scenarios
Real-world data is rarely simple. You will often encounter duplicate values, complex objects, or the need for multi-level sorting.
Handling Tie-Breakers (Secondary Sort)
What happens if two languages have the exact same popularity score? Python’s sort is stable, meaning it preserves the original order of items that compare equal. Even so, relying on insertion order for tie-breaking is implicit. It is best practice to define an explicit secondary key.
You can return a tuple from the lambda function. Python compares tuples element by element: first element, then second, and so on.
data = {
'Task A': (5, 10), # (Priority, Timestamp)
'Task B': (3, 5),
'Task C': (5, 2), # Same priority as A, earlier timestamp
'Task D': (1, 8)
}
# Sort by Priority (asc), then by Timestamp (asc)
# We want Priority low-to-high, Timestamp low-to-high
sorted_tasks = sorted(data.items(), key=lambda item: (item[1][0], item[1][1]))
# Result: Task D (1), Task B (3), Task C (5, 2), Task A (5, 10)
If you wanted Priority descending but Timestamp ascending (do high priority first, but older tasks first within that priority), you can negate the numeric value for the descending part:
# -item[1][0] for descending priority, item[1][1] for ascending timestamp
sorted_complex = sorted(data.items(), key=lambda item: (-item[1][0], item[1][1]))
Sorting by Value with operator.itemgetter
While lambda functions are readable and flexible, the operator module provides itemgetter, which is implemented in C and offers a slight performance boost for large datasets. It is also arguably cleaner for simple index access.
from operator import itemgetter
# itemgetter(1) fetches the second element of the tuple (the value)
sorted_fast = sorted(language_popularity.items(), key=itemgetter(1), reverse=True)
# For multi-level sorting:
# itemgetter(1, 0) sorts by value (index 1), then by key (index 0)
sorted_multi = sorted(language_popularity.items(), key=itemgetter(1, 0))
Sorting Dictionaries with Complex Values
If your dictionary values are objects, lists, or dictionaries, you simply figure out the structure inside the key function.
employees = {
'Alice': {'dept': 'Engineering', 'salary': 90000, 'years': 5},
'Bob': {'dept': 'Sales', 'salary': 75000, 'years': 3},
'Charlie': {'dept': 'Engineering', 'salary': 95000, 'years': 2}
}
# Sort by salary (descending)
by_salary = dict(sorted(employees.items(), key=lambda x: x[1]['salary'], reverse=True))
# Sort by department (asc), then by years of experience (desc)
by_dept_exp = dict(sorted(employees.items(), key=lambda x: (x[1]['dept'], -x[1]['years'])))
Alternative Approaches and Specialized Structures
While sorted() + dict() is the standard "Pythonic" way for modern versions (
versions such as Python 3.7+—where dictionaries preserve insertion order—makes converting back to a dictionary straightforward after sorting. This approach remains the most Pythonic and efficient method for most use cases involving simple key-based sorting Still holds up..
For more elaborate scenarios—such as when dealing with deeply nested structures or when you need stable sorting across multiple levels of complexity—consider leveraging specialized libraries. The pandas library excels at handling large-scale data sorting, especially when working with DataFrames. You can apply similar multi-level sorting logic directly on columns, often resulting in better performance due to optimized underlying implementations:
import pandas as pd
df = pd.DataFrame({
'task': ['A', 'B', 'C', 'D'],
'priority': [5, 3, 5, 1],
'timestamp': [10, 5, 2, 8]
})
# Sort by priority (asc), then timestamp (asc)
result = df.sort_values(by=['priority', 'timestamp'])
print(result)
When building production systems, always account for potential missing keys or malformed entries that might cause KeyError exceptions during sorting. A reliable pattern involves providing default fallback values:
def safe_sort_key(item):
priority = item.get('priority', float('inf'))
timestamp = item.get('timestamp', float('inf'))
return (priority, timestamp)
sorted_items = sorted(data.items(), key=safe_sort_key)
This defensive approach ensures that incomplete records do not disrupt the entire sort operation while still maintaining logical ordering based on available attributes.
To keep it short, mastering these sorting techniques equips developers with powerful tools for organizing and prioritizing data efficiently. Whether you choose pure Python with lambda functions, operator.itemgetter for speed, or external libraries like pandas for massive datasets, understanding the trade-offs between readability, performance, and flexibility will help you select the optimal strategy for each scenario. By applying clear, intentional sorting rules—and avoiding reliance solely on implicit insertion order—you can transform raw, unordered collections into well-structured, actionable results.