Reputation: 21
Totally a programming newbie..and need some help.
What I have is a list of dictionaries in the following format:
a_list = [
{'ID': 'a', 'Animal': 'dog', 'color': 'white', 'tail': 'yes'},
{'ID': 'a', 'Animal': 'cat', 'color': 'black', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'bird', 'color': 'black', 'tail': 'no'},
{'ID': 'b', 'Animal': 'cat', 'color': 'pink', 'tail': 'yes'}
{'ID': 'b', 'Animal': 'dog', 'color': 'yellow', 'tail': 'no'}
]
What I am going for is a dict of dictionaries as follows:
a_dict =
{'a': {'dog': {'color': 'white', 'tail': 'yes'},
'cat': {'color': 'black', 'tail': 'yes'}},
'b': {'bird': {'color': 'black', 'tail': 'no'},
'cat': {'color': 'pink', 'tail': 'no'},
'dog': {'color': 'yellow', 'tail': 'no'}}}
Upvotes: 0
Views: 80
Reputation: 884
You can construct the dictionary iteratively creating inner dictionaries at every step. Here's a suggestion implementation for the general case:
def group_by_nested_keys(elements, keys):
root = {}
for element in elements:
inner_dict = root
# Create the inner dictionaries as we go through the keys
# and remove the key from element at the same time
for key in keys[:-1]:
inner_dict = inner_dict.setdefault(element.pop(key), {})
# When all the dictionaries for the elements are created,
# assign the element to the most inner dictionary
inner_dict[element.pop(keys[-1])] = element
return root
a_dict = group_by_nested_keys(a_list, ["ID", "Animal"])
Upvotes: 0
Reputation: 6573
Much like the other solutions offered here, this uses a default dictionary.
>>> from collections import defaultdict
>>> d = defaultdict(dict)
>>> for dict_ in a_list:
ID = dict_.pop('ID')
animal = dict_.pop('Animal')
d[ID][animal] = dict_
>>> from pprint import pprint
>>> pprint(dict(d))
{'a': {'cat': {'color': 'black', 'tail': 'yes'},
'dog': {'color': 'white', 'tail': 'yes'}},
'b': {'bird': {'color': 'black', 'tail': 'no'},
'cat': {'color': 'pink', 'tail': 'yes'},
'dog': {'color': 'yellow', 'tail': 'no'}}}
Upvotes: 0
Reputation: 5036
An easy solution with defaultdict
from collections import defaultdict
result = defaultdict(dict)
a_list = [
{'ID': 'a', 'Animal': 'dog', 'color': 'white', 'tail': 'yes'},
{'ID': 'a', 'Animal': 'cat', 'color': 'black', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'bird', 'color': 'black', 'tail': 'no'},
{'ID': 'b', 'Animal': 'cat', 'color': 'pink', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'dog', 'color': 'yellow', 'tail': 'no'}
]
for item in a_list:
result[item['ID']][item['Animal']] = {'color':item['color'], 'tail':item['tail']}
defaultdict(dict,
{'a': {'dog': {'color': 'white', 'tail': 'yes'},
'cat': {'color': 'black', 'tail': 'yes'}},
'b': {'bird': {'color': 'black', 'tail': 'no'},
'cat': {'color': 'pink', 'tail': 'yes'},
'dog': {'color': 'yellow', 'tail': 'no'}}})
Upvotes: 0
Reputation: 195418
a_list = [
{'ID': 'a', 'Animal': 'dog', 'color': 'white', 'tail': 'yes'},
{'ID': 'a', 'Animal': 'cat', 'color': 'black', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'bird', 'color': 'black', 'tail': 'no'},
{'ID': 'b', 'Animal': 'cat', 'color': 'pink', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'dog', 'color': 'yellow', 'tail': 'no'}
]
a_dict = {}
for v in a_list:
a_dict.setdefault(v['ID'], {}).setdefault(v['Animal'], {}).update(color=v['color'], tail=v['tail'])
from pprint import pprint
pprint(a_dict)
Prints:
{'a': {'cat': {'color': 'black', 'tail': 'yes'},
'dog': {'color': 'white', 'tail': 'yes'}},
'b': {'bird': {'color': 'black', 'tail': 'no'},
'cat': {'color': 'pink', 'tail': 'yes'},
'dog': {'color': 'yellow', 'tail': 'no'}}}
Upvotes: 1
Reputation: 2477
Created a nested dictionary and deleted all the keys not required later from it.
a_list = [
{'ID': 'a', 'Animal': 'dog', 'color': 'white', 'tail': 'yes'},
{'ID': 'a', 'Animal': 'cat', 'color': 'black', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'bird', 'color': 'black', 'tail': 'no'},
{'ID': 'b', 'Animal': 'cat', 'color': 'pink', 'tail': 'yes'},
{'ID': 'b', 'Animal': 'dog', 'color': 'yellow', 'tail': 'no'}
]
a_dict = {}
for a in a_list:
if a['ID'] in a_dict:
a_dict[a['ID']][a['Animal']] = a
else:
a_dict[a['ID']] = {a['Animal']: a}
for id_ in a_dict:
for animal in a_dict[id_]:
del a_dict[id_][animal]['ID']
del a_dict[id_][animal]['Animal']
Output :
>> a_dict
{'a': {'dog': {'color': 'white', 'tail': 'yes'},
'cat': {'color': 'black', 'tail': 'yes'}},
'b': {'bird': {'color': 'black', 'tail': 'no'},
'cat': {'color': 'pink', 'tail': 'yes'},
'dog': {'color': 'yellow', 'tail': 'no'}}}
Upvotes: 0