Reputation: 1810
So I have the following list of dictionaries that I have initialized with either blank
, None
, or empty values
. What is the proper way to go through each dictionary of the list and check if an attribute meets those criteria and removes them.
members = [{
"member_id": 0,
'title': "Manager",
'full_name': "John Doe",
'first_name': None,
'last_name': None,
'age': 0,
},{
"member_id": 1,
'title': " ",
'full_name': "Jane Doe",
'first_name': "Jane",
'last_name': None,
'age': 10,
},{...}]
[v for k, v in enumerate(members) if members[k] is not None]
I should expect the following result:
members = [{
'title': "Manager",
'full_name': "John Doe",
},{
"member_id": 1,
'full_name': "Jane Doe",
'first_name': "Jane",
'age': 10,
},{...}]
But it seems like my code is returning the same list. What am I doing wrong here. Thanks
EDIT: In case I have nested properties, such as address, How do I go about doing the same thing?
members = [{
"member_id": 0,
'title': "Manager",
'full_name': "John Doe",
'first_name': None,
'last_name': None,
'age': 0,
'address': {
'street_number': 123,
'street_name': None,
'city': "SF",
'state': "CA",
'zip': None,
'full_address': '123 Main Street, San Francisco, CA 94103'
}
},{
"member_id": 1,
'title': " ",
'full_name': "Jane Doe",
'first_name': "Jane",
'last_name': None,
'age': 10,
'address': {
'street_number': None,
'street_name': None,
'city': None,
'state': None,
'zip': None,
'full_address': '123 Main Street, San Francisco, CA 94103'
}
}]
Upvotes: 2
Views: 146
Reputation: 195408
One solution using recursion:
members = [{
"member_id": 0,
'title': "Manager",
'full_name': "John Doe",
'first_name': None,
'last_name': None,
'age': 0,
'address': {
'street_number': 123,
'street_name': None,
'city': "SF",
'state': "CA",
'zip': None,
'full_address': '123 Main Street, San Francisco, CA 94103'
}
},{
"member_id": 1,
'title': " ",
'full_name': "Jane Doe",
'first_name': "Jane",
'last_name': None,
'age': 10,
'address': {
'street_number': None,
'street_name': None,
'city': None,
'state': None,
'zip': None,
'full_address': '123 Main Street, San Francisco, CA 94103'
}
}]
def traverse(m):
if isinstance(m, list):
return list(v for v in (traverse(i) for i in m) if v)
elif isinstance(m, dict):
return dict((k, v) for k, v in ((k, traverse(v)) for k, v in m.items()) if v)
else:
return None if isinstance(m, str) and not m.strip() else m
filtered_members = traverse(members)
from pprint import pprint
pprint(filtered_members)
Prints:
[{'address': {'city': 'SF',
'full_address': '123 Main Street, San Francisco, CA 94103',
'state': 'CA',
'street_number': 123},
'full_name': 'John Doe',
'title': 'Manager'},
{'address': {'full_address': '123 Main Street, San Francisco, CA 94103'},
'age': 10,
'first_name': 'Jane',
'full_name': 'Jane Doe',
'member_id': 1}]
Upvotes: 1
Reputation: 32244
A dictionary can be made out of another dictionary while filtering out "falsy" values with a dictionary comprehension
{k: v for k, v in d.items() if v}
Looks like you expect other values to be filtered out like 0
and ' '
you can add these to the condition
{k: v for k, v in d.items() if v not in (None, ' ', 0)}
Then you can use a list comprehension with this same dictionary comprehension to get what you need
[{k: v for k, v in d.items() if v not in (None, ' ', 0)} for d in members]
EDIT:
For a recursive function that can filter multiple levels of dictionaries
def filter_dictionary(value):
if isinstance(value, dict):
return {k: filter_dictionary(v) for k, v in value.items() if v not in (None, ' ', 0)}
elif value not in (None, ' ', 0):
return value
[filter_dictionary(d) for d in members]
Upvotes: 2
Reputation: 1478
Something like this?
members = [{
"member_id": 0,
'title': "Manager",
'full_name': "John Doe",
'first_name': None,
'last_name': None,
'age': 0,
},{
"member_id": 1,
'title': " ",
'full_name': "Jane Doe",
'first_name': "Jane",
'last_name': None,
'age': 10,
}]
for member in members:
toRemoveKeys = []
for key, value in member.items():
if value in (0, None, " "):
toRemoveKeys.append(key)
for key in toRemoveKeys:
del member[key]
print(members)
Upvotes: 0