I have a function that I use to convert a list of dictionaries into a list of tuples, similar to itertools.groupby()
would do in an ideal world. The goal is to make a list of {unique-dict}
=> [list of values]
. I'm having a hard time explaining it, so I hope the example makes it clear.
I couldn't find a thing on google, so I wrote it pretty quickly, and I am wondering if there is a better way to do this (or a standard library even)
- Naming things is hard... what is a better one?
- This is a task I performed fairly often when receiving user input
- The keys in each dict may not be consistent (some may be missing)
- It is OK to destroy or mangle the original input list & items
- Validation is done before calling, so 'key_field' is always present
- It is expected that values can be duplicated in the list.
{ status: 1 } => [1,2,3,4,1,2]
is ok, if the values are actually present twice.
Simple little python function:
def group_by_excluding_key(list_of_dicts, key_field):
"""
Takes a list of `dict` items and groups by ALL KEYS in the dict EXCEPT the key_field.
:param list_of_dicts: List of dicts to group
:param key_field: key field in dict which should be excluded from the grouping
"""
output = []
for item in list_of_dicts:
found = False
item_key = item.pop(key_field)
for existing_group, found_keys in output:
if existing_group.viewitems() == item.viewitems():
found_keys.append(item_key)
found = True
break
if not found:
output.append((item, [item_key]))
return output
Example Input/Output
from pprint import pprint
data = [
{'id': 1, 'status': 1, 'product': 1},
{'id': 2, 'status': 1, 'product': 1},
{'id': 7, 'status': 1, 'product': 2},
{'id': 9, 'status': 1, 'product': 2},
{'id': 3, 'status': 1, 'product': 1},
{'id': 4, 'status': 1, 'product': 1},
{'id': 8, 'status': 1, 'product': 2},
{'id': 1, 'status': 1, 'product': 1},
]
results = group_by_excluding_key(data, 'id')
pprint(results)
# [({u'product': 1, u'status': 1}, [1, 2, 3, 4, 1]),
# ({u'product': 2, u'status': 1}, [7, 9, 8])]