How to remove a key from a dictionary in Python
Use del d[key] when the key must exist, d.pop(key) when you also want the value back, and d.pop(key, None) when a missing key should be a no-op instead of a KeyError.
All three of those mutate the dictionary in place — there is no copy, and every other name pointing at that dict sees the key disappear. Only the comprehension in section 4 builds a new dict and leaves the original alone. Each example runs on this page: hit Run, then edit the code and run it again.
1del d[key]Recommended
del is the direct statement for "this key should not be here anymore". It removes the entry in place and evaluates to nothing — and it raises KeyError if the key was never there, which is exactly what you want when a missing key means a bug upstream.
Output
Output: {'name': 'Ada', 'role': 'admin'}, then False, then KeyError: 'nickname'. If a missing key is fine, guard with if key in d: del d[key] — or skip the guard entirely and use d.pop(key, None) from section 3.
2d.pop(key) — keep the removed value
pop() does everything del does and hands you the value it just removed. Use it whenever the value still matters — moving a field out of a payload, consuming a one-shot token, popping an option out of a **kwargs dict before passing the rest on.
Output
Prints abc123 and then {'name': 'Ada', 'role': 'admin'}. With no second argument, pop() raises KeyError on a missing key, just like del.
3d.pop(key, None) — never raises
Give pop() a second argument and a missing key stops being an error: you get the default back instead. d.pop(key, None) is the idiomatic "remove it if it is there" one-liner — no in check, no try/except.
Output
Output: None, admin, {'name': 'Ada'}, (nothing to remove). The catch is that the return value alone can't tell you whether the key was absent or present-but-None — check key in d first if you need to distinguish those.
4A dict comprehension for several keys
To drop a whole group of keys, filter with a comprehension instead of looping over del. This is the one approach here that does not mutate: it returns a new dict and the original is untouched — usually what you want when you're producing a redacted or public view of a record.
Output
Prints {'id': 7, 'name': 'Ada', 'role': 'admin'} and then the original record, still complete. Keep the keys to drop in a set — membership is O(1), and the surviving keys stay in their original insertion order. If you do want the original mutated, loop instead: for k in drop: record.pop(k, None).
5Which should you use?
| Method | Returns value | Missing key | Mutates in place |
|---|---|---|---|
| del d[key] | No | Raises KeyError | Yes |
| d.pop(key) | Yes | Raises KeyError | Yes |
| d.pop(key, None) | Yes | Returns default | Yes |
| {k: v for … if k not in drop} | No | Ignored | No — new dict |
6Common variation: removing keys while iterating
Deleting inside for k in d: raises RuntimeError: dictionary changed size during iteration — the loop iterates over the live dict, so resizing it mid-flight invalidates the iterator. The fix is one call: list(d) snapshots the keys first, so the loop iterates a list while you mutate the dict.
Output
Note the second line of output — {'ada': 91, 'cleo': 78, 'dan': 30}. The failed loop still deleted bob before it blew up, so a RuntimeError here leaves you half-mutated, not unchanged. After the list(d) pass you get {'ada': 91, 'cleo': 78}, and popitem() then removes and returns the last inserted pair, ('cleo', 78).
Frequently asked questions
What is the difference between del and pop() in Python dictionaries?
Both remove the key in place, but del d[key] is a statement that returns nothing, while d.pop(key) is a method that returns the removed value. Both raise KeyError on a missing key — only d.pop(key, default) does not.
How do I remove a key from a dict without a KeyError?
Use d.pop(key, None). It removes the key if present and returns None otherwise, so a missing key is a no-op. The alternatives are if key in d: del d[key] or wrapping del in a try/except KeyError.
How do I remove multiple keys from a dictionary at once?
For a new dict, filter with a comprehension: {k: v for k, v in d.items() if k not in drop}, where drop is a set of keys. To mutate the original instead, loop: for k in drop: d.pop(k, None).
Why does deleting a key inside a for loop raise RuntimeError?
Iterating a dict with for k in d: walks the live dict, so changing its size mid-loop invalidates the iterator and Python raises RuntimeError: dictionary changed size during iteration. Iterate a snapshot instead — for k in list(d): — or build a filtered dict with a comprehension.