How can I remove a key from a Python dictionary?
Question:
I want to remove a key from a dictionary if it is present. I currently use this code:
if key in my_dict:
del my_dict[key]
Without the if
statement, the code will raise KeyError
if the key is not present. How can I handle this more simply?
See Delete an element from a dictionary for more general approaches to the problem of removing a key from a dict (including ones which produce a modified copy).
Answers:
To delete a key regardless of whether it is in the dictionary, use the two-argument form of dict.pop()
:
my_dict.pop('key', None)
This will return my_dict[key]
if key
exists in the dictionary, and None
otherwise. If the second parameter is not specified (i.e. my_dict.pop('key')
) and key
does not exist, a KeyError
is raised.
To delete a key that is guaranteed to exist, you can also use
del my_dict['key']
This will raise a KeyError
if the key is not in the dictionary.
Specifically to answer “is there a one line way of doing this?”
if 'key' in my_dict: del my_dict['key']
…well, you asked 😉
You should consider, though, that this way of deleting an object from a dict
is not atomic—it is possible that 'key'
may be in my_dict
during the if
statement, but may be deleted before del
is executed, in which case del
will fail with a KeyError
. Given this, it would be safest to either use dict.pop
or something along the lines of
try:
del my_dict['key']
except KeyError:
pass
which, of course, is definitely not a one-liner.
It took me some time to figure out what exactly my_dict.pop("key", None)
is doing. So I’ll add this as an answer to save others googling time:
pop(key[, default])
If key is in the dictionary, remove it and return its value, else
return default. If default is not given and key is not in the
dictionary, a KeyError
is raised.
If you need to remove a lot of keys from a dictionary in one line of code, I think using map() is quite succinct and Pythonic readable:
myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}
And if you need to catch errors where you pop a value that isn’t in the dictionary, use lambda inside map() like this:
map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}
or in python3
, you must use a list comprehension instead:
[myDict.pop(x, None) for x in ['a', 'c', 'e']]
It works. And ‘e’ did not cause an error, even though myDict did not have an ‘e’ key.
You can use a dictionary comprehension to create a new dictionary with that key removed:
>>> my_dict = {k: v for k, v in my_dict.items() if k != 'key'}
You can delete by conditions. No error if key
doesn’t exist.
del my_dict[key]
is slightly faster than my_dict.pop(key)
for removing a key from a dictionary when the key exists
>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"
>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786
But when the key doesn’t exist if key in my_dict: del my_dict[key]
is slightly faster than my_dict.pop(key, None)
. Both are at least three times faster than del
in a try
/except
statement:
>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
... del d['missing key']
... except KeyError:
... pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133
We can delete a key from a Python dictionary by the some of the following approaches.
Using the del
keyword; it’s almost the same approach like you did though –
myDict = {'one': 100, 'two': 200, 'three': 300 }
print(myDict) # {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : del myDict['one']
print(myDict) # {'two': 200, 'three': 300}
Or
We can do like the following:
But one should keep in mind that, in this process actually it won’t delete any key from the dictionary rather than making a specific key excluded from that dictionary. In addition, I observed that it returned a dictionary which was not ordered the same as myDict
.
myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}
If we run it in the shell, it’ll execute something like {'five': 500, 'four': 400, 'three': 300, 'two': 200}
– notice that it’s not the same ordered as myDict
. Again if we try to print myDict
, then we can see all keys including which we excluded from the dictionary by this approach. However, we can make a new dictionary by assigning the following statement into a variable:
var = {key:value for key, value in myDict.items() if key != 'one'}
Now if we try to print it, then it’ll follow the parent order:
print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}
Or
Using the pop()
method.
myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)
if myDict.get('one') : myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
The difference between del
and pop
is that, using pop()
method, we can actually store the key’s value if needed, like the following:
myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var) # 100
Fork this gist for future reference, if you find this useful.
You can use exception handling if you want to be very verbose:
try:
del dict[key]
except KeyError: pass
This is slower, however, than the pop()
method, if the key doesn’t exist.
my_dict.pop('key', None)
It won’t matter for a few keys, but if you’re doing this repeatedly, then the latter method is a better bet.
The fastest approach is this:
if 'key' in dict:
del myDict['key']
But this method is dangerous because if 'key'
is removed in between the two lines, a KeyError
will be raised.
I prefer the immutable version
foo = {
1:1,
2:2,
3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
return {
k:v
for k,v in dct.items() if k not in keyIter
}
>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}
Another way is by using items() + dict comprehension.
items() coupled with dict comprehension can also help us achieve the task of key-value pair deletion, but it has the drawback of not being an in place dict technique. Actually a new dict if created except for the key we don’t wish to include.
test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21}
# Printing dictionary before removal
print ("dictionary before performing remove is : " + str(test_dict))
# Using items() + dict comprehension to remove a dict. pair
# removes vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'}
# Printing dictionary after removal
print ("dictionary after remove is : " + str(new_dict))
Output:
dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}
Remove multiple keys
Marc Maxmeister’s post discusses this but creates an unnecessary (imo) list while doing so. You can simply use a for-loop and throw away the popped values.
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
lst = ['a', 'c', 'e']
for k in lst: my_dict.pop(k, None)
print(my_dict) # {'b': 2, 'd': 4}
or if you want to use map
, then exhaust the map using a deque with max length 0.
from collections import deque
from itertools import repeat
deque(map(my_dict.pop, ['a', 'c', 'e'], repeat(None)), 0)
print(my_dict) # {'b': 2, 'd': 4}
Split dict into two
One case where dict.pop()
may be useful is if you want to create a new dictionary with the popped key-value pairs, effectively splitting a dictionary into two in one for-loop.
new_dict = {k: v for k in lst if (v:=my_dict.pop(k, 'NULL')) != 'NULL'}
print(my_dict) # {'b': 2, 'd': 4}
print(new_dict) # {'a': 1, 'c': 3}
I want to remove a key from a dictionary if it is present. I currently use this code:
if key in my_dict:
del my_dict[key]
Without the if
statement, the code will raise KeyError
if the key is not present. How can I handle this more simply?
See Delete an element from a dictionary for more general approaches to the problem of removing a key from a dict (including ones which produce a modified copy).
To delete a key regardless of whether it is in the dictionary, use the two-argument form of dict.pop()
:
my_dict.pop('key', None)
This will return my_dict[key]
if key
exists in the dictionary, and None
otherwise. If the second parameter is not specified (i.e. my_dict.pop('key')
) and key
does not exist, a KeyError
is raised.
To delete a key that is guaranteed to exist, you can also use
del my_dict['key']
This will raise a KeyError
if the key is not in the dictionary.
Specifically to answer “is there a one line way of doing this?”
if 'key' in my_dict: del my_dict['key']
…well, you asked 😉
You should consider, though, that this way of deleting an object from a dict
is not atomic—it is possible that 'key'
may be in my_dict
during the if
statement, but may be deleted before del
is executed, in which case del
will fail with a KeyError
. Given this, it would be safest to either use dict.pop
or something along the lines of
try:
del my_dict['key']
except KeyError:
pass
which, of course, is definitely not a one-liner.
It took me some time to figure out what exactly my_dict.pop("key", None)
is doing. So I’ll add this as an answer to save others googling time:
pop(key[, default])
If key is in the dictionary, remove it and return its value, else
return default. If default is not given and key is not in the
dictionary, aKeyError
is raised.
If you need to remove a lot of keys from a dictionary in one line of code, I think using map() is quite succinct and Pythonic readable:
myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}
And if you need to catch errors where you pop a value that isn’t in the dictionary, use lambda inside map() like this:
map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}
or in python3
, you must use a list comprehension instead:
[myDict.pop(x, None) for x in ['a', 'c', 'e']]
It works. And ‘e’ did not cause an error, even though myDict did not have an ‘e’ key.
You can use a dictionary comprehension to create a new dictionary with that key removed:
>>> my_dict = {k: v for k, v in my_dict.items() if k != 'key'}
You can delete by conditions. No error if key
doesn’t exist.
del my_dict[key]
is slightly faster than my_dict.pop(key)
for removing a key from a dictionary when the key exists
>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"
>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786
But when the key doesn’t exist if key in my_dict: del my_dict[key]
is slightly faster than my_dict.pop(key, None)
. Both are at least three times faster than del
in a try
/except
statement:
>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
... del d['missing key']
... except KeyError:
... pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133
We can delete a key from a Python dictionary by the some of the following approaches.
Using the del
keyword; it’s almost the same approach like you did though –
myDict = {'one': 100, 'two': 200, 'three': 300 }
print(myDict) # {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : del myDict['one']
print(myDict) # {'two': 200, 'three': 300}
Or
We can do like the following:
But one should keep in mind that, in this process actually it won’t delete any key from the dictionary rather than making a specific key excluded from that dictionary. In addition, I observed that it returned a dictionary which was not ordered the same as myDict
.
myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}
If we run it in the shell, it’ll execute something like {'five': 500, 'four': 400, 'three': 300, 'two': 200}
– notice that it’s not the same ordered as myDict
. Again if we try to print myDict
, then we can see all keys including which we excluded from the dictionary by this approach. However, we can make a new dictionary by assigning the following statement into a variable:
var = {key:value for key, value in myDict.items() if key != 'one'}
Now if we try to print it, then it’ll follow the parent order:
print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}
Or
Using the pop()
method.
myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)
if myDict.get('one') : myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
The difference between del
and pop
is that, using pop()
method, we can actually store the key’s value if needed, like the following:
myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var) # 100
Fork this gist for future reference, if you find this useful.
You can use exception handling if you want to be very verbose:
try:
del dict[key]
except KeyError: pass
This is slower, however, than the pop()
method, if the key doesn’t exist.
my_dict.pop('key', None)
It won’t matter for a few keys, but if you’re doing this repeatedly, then the latter method is a better bet.
The fastest approach is this:
if 'key' in dict:
del myDict['key']
But this method is dangerous because if 'key'
is removed in between the two lines, a KeyError
will be raised.
I prefer the immutable version
foo = {
1:1,
2:2,
3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
return {
k:v
for k,v in dct.items() if k not in keyIter
}
>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}
Another way is by using items() + dict comprehension.
items() coupled with dict comprehension can also help us achieve the task of key-value pair deletion, but it has the drawback of not being an in place dict technique. Actually a new dict if created except for the key we don’t wish to include.
test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21}
# Printing dictionary before removal
print ("dictionary before performing remove is : " + str(test_dict))
# Using items() + dict comprehension to remove a dict. pair
# removes vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'}
# Printing dictionary after removal
print ("dictionary after remove is : " + str(new_dict))
Output:
dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}
Remove multiple keys
Marc Maxmeister’s post discusses this but creates an unnecessary (imo) list while doing so. You can simply use a for-loop and throw away the popped values.
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
lst = ['a', 'c', 'e']
for k in lst: my_dict.pop(k, None)
print(my_dict) # {'b': 2, 'd': 4}
or if you want to use map
, then exhaust the map using a deque with max length 0.
from collections import deque
from itertools import repeat
deque(map(my_dict.pop, ['a', 'c', 'e'], repeat(None)), 0)
print(my_dict) # {'b': 2, 'd': 4}
Split dict into two
One case where dict.pop()
may be useful is if you want to create a new dictionary with the popped key-value pairs, effectively splitting a dictionary into two in one for-loop.
new_dict = {k: v for k in lst if (v:=my_dict.pop(k, 'NULL')) != 'NULL'}
print(my_dict) # {'b': 2, 'd': 4}
print(new_dict) # {'a': 1, 'c': 3}