Filter dict to contain only certain keys?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Filtering a dictionary to keep only the keys you care about is one of the most common operations when working with data in Python. You encounter it when processing API responses that return dozens of fields but you only need three, or when sanitizing user input before passing it to a function. Python gives you several clean ways to do this, each with different tradeoffs.
This article covers four approaches: dictionary comprehension, the dict constructor with a generator, operator.itemgetter, and set intersection with direct key access.
Dictionary Comprehension
The most Pythonic and widely used approach is a dictionary comprehension that iterates over the desired keys and picks values from the source dictionary.
This iterates over every key-value pair in the original dictionary and keeps only those whose key is in allowed_keys. Using a set for allowed_keys gives O(1) membership checks, so the overall time complexity is O(n) where n is the size of the original dictionary.
If you want to be safe when the allowed keys might not exist in the original, this pattern handles it gracefully because the if condition simply skips missing keys.
Dict Constructor with a Generator
You can also pass a generator expression to the dict() constructor. This is functionally identical to the comprehension but some developers find it reads more clearly when the filtering logic is simple.
Notice that this version iterates over allowed_keys rather than over the original dictionary. When allowed_keys is much smaller than the original dictionary, this approach does less work. The if k in original guard prevents KeyError for keys that do not exist in the source.
Using operator.itemgetter
The operator.itemgetter function retrieves multiple values from a dictionary in a single call. This is useful when you know all the desired keys exist and you want both the keys and values extracted together.
One important detail: if any key in keys_to_keep is missing from the original dictionary, itemgetter raises a KeyError. This makes it a good choice when you want to enforce that all expected keys are present, essentially treating the filtering as a strict projection. Also note that when keys_to_keep contains only one element, itemgetter returns a single value instead of a tuple, so you need to handle that edge case if the number of keys is dynamic.
Set Intersection with Direct Key Access
This pattern uses set intersection to find which of your desired keys actually exist in the dictionary, then builds a new dictionary from those keys.
The & operator works because dict.keys() returns a view object that supports set operations. This approach makes the intent very explicit: first compute the intersection of available and desired keys, then build the result. It is especially readable when you need to reuse present_keys for other logic, such as logging which requested keys were missing.
Choosing the Right Approach
| Approach | Handles missing keys | Iterates over | Best when |
| Dict comprehension | Yes (skips them) | Original dict | General purpose, most common |
| Dict constructor + generator | Yes (with guard) | Allowed keys | Allowed set is much smaller |
operator.itemgetter | No (raises KeyError) | Allowed keys | You want strict validation |
| Set intersection | Yes (intersection filters) | Intersection | You need the key overlap explicitly |
Common Pitfalls
- Using a list instead of a set for allowed keys. Membership checks in a list are O(n), while a set gives O(1). For large dictionaries or large key lists, this difference matters.
- Forgetting to handle missing keys. If you write
{k: original[k] for k in allowed_keys}without a guard, any key inallowed_keysthat is not in the original dictionary raises aKeyError. Useif k in originalor thedict.getmethod. - Mutating the original dictionary instead of creating a new one. Deleting keys from the original with a loop like
for k in list(d.keys()): if k not in allowed: del d[k]modifies the source data, which can cause bugs if other code holds a reference to it. - Assuming dictionary order does not matter. Since Python 3.7, dictionaries maintain insertion order. If you filter by iterating over
allowed_keys, the result follows the order ofallowed_keys, not the original dictionary. This can matter for serialization or display. - Overcomplicating simple filters. For straightforward cases, a one-line dictionary comprehension is the clearest and most maintainable option. Reaching for
itemgetteror multi-step set operations when a comprehension would suffice adds unnecessary complexity.
Summary
- Dictionary comprehension (
{k: v for k, v in d.items() if k in allowed}) is the default choice for filtering dictionaries in Python. - When the set of desired keys is much smaller than the dictionary, iterate over the keys instead of the dictionary for better performance.
operator.itemgetteris useful when you want strict validation that all requested keys exist.- Set intersection (
d.keys() & allowed) makes the overlap between available and desired keys explicit and reusable. - Always use a set (not a list) for the collection of allowed keys to ensure O(1) membership checks.

