I have a list of dictionaries with the following stucture:
list_of_dicts = [
{'id': 1, 'fruits':['apple']},
{'id': 2, 'fruits':['orange']},
{'id': 3, 'fruits':['banana', 'apple']},
{'id': 4, 'fruits':['banana', 'apple', 'orange']}
]
I want to filter the list_of_dicts
by the elements contained in the 'fruits'
keys. Specifically, I want to compare the fruits a list of acceptable fruits:
acceptable_fruits = ['apple', 'banana']
the expected result of this filter should be a list like this:
expected_result = [
{'id': 1, 'fruits':['apple']},
{'id': 3, 'fruits':['banana', 'apple']},
{'id': 4, 'fruits':['banana', 'apple', 'orange']}]
I have attempted to nested filter statements, but that does not seem to work:
filtered_list = filter(lambda dict: filter(lambda fruit: fruit in acceptable_fruits, dict['fruits']), list_of_dicts)
The return in this case is the original list:
print(list(filtered_list))
returns:
[{'id': 1, 'fruits': ['apple']}, {'id': 2, 'fruits': ['orange']}, {'id': 3, 'fruits': ['banana', 'apple']}, {'id': 4, 'fruits': ['banana', 'apple', 'orange']}]
Other iterating loops have not worked well for me either. Does anybody have a good way of doing this?
CodePudding user response:
The problem is that filter
doesn't return a list in Python 3. Obviously, you're handling that for the outer filter with list(filtered_list)
, but the inner filter
is not handled, so it's evalutating as True
, like this:
>>> f = filter(None, [])
>>> bool(f)
True
To fix it, you could just wrap the inner filter
in list()
, but really what you're trying to ask is "is any fruit in acceptable_fruits
?", which is better written with any()
. And besides, list(filter(lambda))
is better written as a comprehension, for both inner and outer:
filtered_list = [
d for d in list_of_dicts
if any(fruit in acceptable_fruits for fruit in d['fruits'])]
Result:
[{'id': 1, 'fruits': ['apple']},
{'id': 3, 'fruits': ['banana', 'apple']},
{'id': 4, 'fruits': ['banana', 'apple', 'orange']}]
CodePudding user response:
can be easy with sets
list_of_dicts = [
{'id': 1, 'fruits':{'apple'}},
{'id': 2, 'fruits':{'orange'}},
{'id': 3, 'fruits':{'banana', 'apple'}},
{'id': 4, 'fruits':{'banana', 'apple', 'orange'}}
]
acceptable_fruits = {'apple', 'banana'}
result=[d for d in list_of_dicts if acceptable_fruits & d['fruits']]
print(result)
>>> [{'id': 1, 'fruits': {'apple'}}, {'id': 3, 'fruits': {'banana', 'apple'}}, {'id': 4, 'fruits': {'banana', 'apple', 'orange'}}]