Python
Dictionary
Data Structures
Key Removal
Programming Tips

Removing multiple keys from a dictionary safely

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

To remove multiple keys from a Python dictionary safely (without raising KeyError for missing keys), use dictionary comprehension to create a new dict excluding the unwanted keys, or use dict.pop(key, None) in a loop to remove keys in place. The "safely" part means handling keys that may not exist in the dictionary. This article covers all common approaches — comprehension, pop(), del with checks, and set operations — with their tradeoffs in readability, performance, and whether they modify the original dictionary or create a new one.

Method 1: Dictionary Comprehension (New Dict)

Create a new dictionary excluding the unwanted keys:

python
1data = {"name": "Alice", "age": 30, "email": "[email protected]",
2        "phone": "555-1234", "city": "NYC"}
3
4keys_to_remove = {"email", "phone", "address"}  # "address" doesn't exist — no error
5
6filtered = {k: v for k, v in data.items() if k not in keys_to_remove}
7print(filtered)
8# {'name': 'Alice', 'age': 30, 'city': 'NYC'}
9
10# Original is unchanged
11print(data)
12# {'name': 'Alice', 'age': 30, 'email': '[email protected]', 'phone': '555-1234', 'city': 'NYC'}

Using a set for keys_to_remove gives O(1) lookup per key, making this O(n) overall where n is the dictionary size.

Method 2: pop() in a Loop (In-Place)

dict.pop(key, default) removes a key and returns its value, or returns default if the key does not exist:

python
1data = {"name": "Alice", "age": 30, "email": "[email protected]",
2        "phone": "555-1234", "city": "NYC"}
3
4keys_to_remove = ["email", "phone", "address"]  # "address" doesn't exist
5
6for key in keys_to_remove:
7    data.pop(key, None)  # None = default if key missing, no KeyError
8
9print(data)
10# {'name': 'Alice', 'age': 30, 'city': 'NYC'}

This modifies the dictionary in place and is O(k) where k is the number of keys to remove.

Method 3: del with Key Check (In-Place)

python
1data = {"name": "Alice", "age": 30, "email": "[email protected]"}
2keys_to_remove = ["email", "phone"]
3
4for key in keys_to_remove:
5    if key in data:
6        del data[key]
7
8print(data)
9# {'name': 'Alice', 'age': 30}

Functionally identical to pop() but uses del instead. Slightly less concise since it requires an explicit if check.

Method 4: Set Difference on Keys (New Dict)

Use set arithmetic to compute the keys to keep:

python
1data = {"name": "Alice", "age": 30, "email": "[email protected]",
2        "phone": "555-1234", "city": "NYC"}
3
4keys_to_remove = {"email", "phone", "address"}
5keys_to_keep = data.keys() - keys_to_remove
6
7filtered = {k: data[k] for k in keys_to_keep}
8print(filtered)
9# {'name': 'Alice', 'age': 30, 'city': 'NYC'}

dict.keys() returns a set-like view, so - computes the set difference directly.

Method 5: Using a Helper Function

python
1def remove_keys(d, keys, in_place=False):
2    """Remove multiple keys from a dictionary safely."""
3    keys_set = set(keys)
4    if in_place:
5        for key in keys_set:
6            d.pop(key, None)
7        return d
8    return {k: v for k, v in d.items() if k not in keys_set}
9
10data = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
11
12# New dict
13result = remove_keys(data, ["b", "d", "f"])
14print(result)  # {'a': 1, 'c': 3, 'e': 5}
15print(data)    # Unchanged
16
17# In-place
18remove_keys(data, ["b", "d", "f"], in_place=True)
19print(data)    # {'a': 1, 'c': 3, 'e': 5}

Method 6: Keeping Only Specified Keys

Sometimes it is easier to specify which keys to keep rather than which to remove:

python
1data = {"name": "Alice", "age": 30, "email": "[email protected]",
2        "phone": "555-1234", "city": "NYC", "country": "US"}
3
4keys_to_keep = {"name", "age", "city"}
5filtered = {k: v for k, v in data.items() if k in keys_to_keep}
6print(filtered)
7# {'name': 'Alice', 'age': 30, 'city': 'NYC'}

Performance Comparison

python
1import timeit
2
3data = {f"key_{i}": i for i in range(10000)}
4keys_to_remove = {f"key_{i}" for i in range(0, 10000, 2)}  # Remove 5000 keys
5
6# Comprehension
7t1 = timeit.timeit(
8    lambda: {k: v for k, v in data.items() if k not in keys_to_remove},
9    number=1000
10)
11
12# pop() loop
13def pop_method():
14    d = dict(data)
15    for k in keys_to_remove:
16        d.pop(k, None)
17    return d
18
19t2 = timeit.timeit(pop_method, number=1000)
20
21# Set difference
22t3 = timeit.timeit(
23    lambda: {k: data[k] for k in data.keys() - keys_to_remove},
24    number=1000
25)
26
27# All three are similar — O(n) for comprehension, O(k) for pop
MethodCreates New Dict?Safe for Missing Keys?Complexity
ComprehensionYesYesO(n)
pop() loopNo (in-place)YesO(k)
del with checkNo (in-place)YesO(k)
Set differenceYesYesO(n)

Common Pitfalls

  • Using del data[key] without checking existence: del raises KeyError if the key does not exist. Always use if key in data: del data[key] or prefer data.pop(key, None) which handles missing keys silently.
  • Iterating over the dictionary while modifying it: for key in data: del data[key] raises RuntimeError: dictionary changed size during iteration. Iterate over a separate list of keys to remove, not over the dictionary itself.
  • Using a list instead of a set for keys_to_remove: With a list, the if k not in keys_to_remove check is O(k) per lookup, making comprehension O(n*k). Using a set makes it O(1) per lookup, keeping overall complexity at O(n).
  • Assuming comprehension modifies the original dict: Dictionary comprehension creates a new dictionary. If other variables reference the original dict, they still see the old data. Use pop() or del for in-place modification when references matter.
  • Not considering None as a valid dictionary value: data.pop(key, None) returns None for both missing keys and keys whose value is None. If you need to distinguish these cases, check key in data before popping.

Summary

  • Use {k: v for k, v in d.items() if k not in keys_set} to create a new dict excluding specific keys
  • Use d.pop(key, None) in a loop for safe in-place removal (no KeyError on missing keys)
  • Convert keys_to_remove to a set for O(1) membership testing
  • Never modify a dictionary while iterating over it — iterate over a separate collection of keys
  • Choose comprehension (new dict) vs pop() (in-place) based on whether you need the original dict to change

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.