问题
A follow up on the recent question Remove keys from object not in a list in python?
That question turns out to be a duplicate of a previous one. All answers there, and among them the most voted, use list comprehension. I'm thinking on a functional approach. How can this be done using filter
?
We have:
testdict={'a':'vala', 'b':'valb', 'c':'valc','d':'vald'}
keep=['a','c']
and I want
filter(isKept,testdict)
to give
{'a':'vala','c':'valc'}
I tried naively defining isKept
as a function of either one (the keys) or two variables (keys, values) but the former just filters out the right keys without the corresponding values (i.e., a list, not a dictionary). The latter way doesn't even parse correctly.
Is there a filter for dictionaries in Python?
Notice that testdict.pop(k)
is not what I want as this deletes, but the question here is to keep.
回答1:
Truth be told using comprehensions is as functional as it gets, but if that's not what you want toolz library provides a nice set of functions including keyfilter
:
>>> from toolz.dicttoolz import keyfilter
>>> to_keep = lambda key: key in set(keep)
>>> keyfilter(to_keep, testdict)
{'a': 'vala', 'c': 'valc'}
回答2:
Functions like filter()
, map()
and reduce()
do not modify the original sequence you pass to them. They return a new sequence or value. In addition to that, if you want to use filter()
on dicts, you should convert it to list first using .items()
or better yet, to an iterator via .iteritems()
:
>>> testdict = {'a':'vala', 'b':'valb', 'c':'valc','d':'vald'}
>>> keep = ['a','c']
>>> print dict(filter(lambda entry: entry[0] in keep, testdict.items()))
{'a': 'vala', 'c': 'valc'}
回答3:
A dict comprehension is as functional as it gets (i.e. it is both declarative and stateless):
{k: v for k, v in d.items() if k in keep}
Furthermore, it is pythonic (i.e. it is explicit, readable, and succinct). You really should prefer this style.
回答4:
testdict={'a':'vala', 'b':'valb', 'c':'valc','d':'vald'}
keep=['a','c']
def isKept(dict_item):
if dict_item[0] in keep:
return True
else:
return False
print(dict(filter(isKept,testdict.items())))
来源:https://stackoverflow.com/questions/32728058/python-functional-approach-remove-key-from-dict-using-filter