Return copy of dictionary excluding specified keys
Question:
I want to make a function that returns a copy of a dictionary excluding keys specified in a list.
Considering this dictionary:
my_dict = {
"keyA": 1,
"keyB": 2,
"keyC": 3
}
A call to without_keys(my_dict, ['keyB', 'keyC'])
should return:
{
"keyA": 1
}
I would like to do this in a one-line with a neat dictionary comprehension but I’m having trouble. My attempt is this:
def without_keys(d, keys):
return {k: d[f] if k not in keys for f in d}
which is invalid syntax. How can I do this?
Answers:
You were close, try the snippet below:
>>> my_dict = {
... "keyA": 1,
... "keyB": 2,
... "keyC": 3
... }
>>> invalid = {"keyA", "keyB"}
>>> def without_keys(d, keys):
... return {x: d[x] for x in d if x not in keys}
>>> without_keys(my_dict, invalid)
{'keyC': 3}
Basically, the if k not in keys
will go at the end of the dict comprehension in the above case.
This should work for you.
def without_keys(d, keys):
return {k: v for k, v in d.items() if k not in keys}
In your dictionary comprehension you should be iterating over your dictionary (not k
, not sure what that is either). Example –
return {k:v for k,v in d.items() if k not in keys}
For those who don’t like list comprehensions, this is my version:
def without_keys(d, *keys):
return dict(filter(lambda key_value: key_value[0] not in keys, d.items()))
Usage:
>>> d={1:3, 5:7, 9:11, 13:15}
>>> without_keys(d, 1, 5, 9)
{13: 15}
>>> without_keys(d, 13)
{1: 3, 5: 7, 9: 11}
>>> without_keys(d, *[5, 7])
{1: 3, 13: 15, 9: 11}
Even shorter. Apparently python 3 lets you ‘subtract’ a list
from a dict_keys
.
def without_keys(d, keys):
return {k: d[k] for k in d.keys() - keys}
You could this generalized for nested dictionaries solution
def copy_dict(data, strip_values=False, remove_keys=[]):
if type(data) is dict:
out = {}
for key, value in data.items():
if key not in remove_keys:
out[key] = copy_dict(value, strip_values=strip_values, remove_keys=remove_keys)
return out
else:
return [] if strip_values else data
This recursive solution works for nested dictionaries and removes keys not required from the entire nested structure. It also gives you the ability to return the nest with only keys and no values.
Your oneliner
my_dict = {"keyA": 1, "keyB": 2, "keyC": 3}
(lambda keyB, keyC, **kw: kw)(**my_dict)
which returns {'keyA': 1}
.
Not very pythonic and dynamic, but hacky and short.
It uses the dict unpacking (destructuring assignment) of function arguments.
I want to make a function that returns a copy of a dictionary excluding keys specified in a list.
Considering this dictionary:
my_dict = {
"keyA": 1,
"keyB": 2,
"keyC": 3
}
A call to without_keys(my_dict, ['keyB', 'keyC'])
should return:
{
"keyA": 1
}
I would like to do this in a one-line with a neat dictionary comprehension but I’m having trouble. My attempt is this:
def without_keys(d, keys):
return {k: d[f] if k not in keys for f in d}
which is invalid syntax. How can I do this?
You were close, try the snippet below:
>>> my_dict = {
... "keyA": 1,
... "keyB": 2,
... "keyC": 3
... }
>>> invalid = {"keyA", "keyB"}
>>> def without_keys(d, keys):
... return {x: d[x] for x in d if x not in keys}
>>> without_keys(my_dict, invalid)
{'keyC': 3}
Basically, the if k not in keys
will go at the end of the dict comprehension in the above case.
This should work for you.
def without_keys(d, keys):
return {k: v for k, v in d.items() if k not in keys}
In your dictionary comprehension you should be iterating over your dictionary (not k
, not sure what that is either). Example –
return {k:v for k,v in d.items() if k not in keys}
For those who don’t like list comprehensions, this is my version:
def without_keys(d, *keys):
return dict(filter(lambda key_value: key_value[0] not in keys, d.items()))
Usage:
>>> d={1:3, 5:7, 9:11, 13:15}
>>> without_keys(d, 1, 5, 9)
{13: 15}
>>> without_keys(d, 13)
{1: 3, 5: 7, 9: 11}
>>> without_keys(d, *[5, 7])
{1: 3, 13: 15, 9: 11}
Even shorter. Apparently python 3 lets you ‘subtract’ a list
from a dict_keys
.
def without_keys(d, keys):
return {k: d[k] for k in d.keys() - keys}
You could this generalized for nested dictionaries solution
def copy_dict(data, strip_values=False, remove_keys=[]):
if type(data) is dict:
out = {}
for key, value in data.items():
if key not in remove_keys:
out[key] = copy_dict(value, strip_values=strip_values, remove_keys=remove_keys)
return out
else:
return [] if strip_values else data
This recursive solution works for nested dictionaries and removes keys not required from the entire nested structure. It also gives you the ability to return the nest with only keys and no values.
Your oneliner
my_dict = {"keyA": 1, "keyB": 2, "keyC": 3}
(lambda keyB, keyC, **kw: kw)(**my_dict)
which returns {'keyA': 1}
.
Not very pythonic and dynamic, but hacky and short.
It uses the dict unpacking (destructuring assignment) of function arguments.