You can give birth to such a function:
from itertools import groupby from collections import defaultdict def group_dicts(data, key_name, joiner=None): """ Groups an iterable of dictionaries on given key. Non-duplicate elements are joined using joiner function. The default implementation uses ",".join(sorted(item_set)), so beware that a TypeError exception may arise on non-string values. Pass an identity function (lambda x: x) to use sets and stay safe. >>> list(group_dicts([ ... {'id': 113, 'ip': '10.10.10.1', 'is_blocked': 0}, ... {'id': 114, 'ip': '10.10.10.2', 'is_blocked': 1}, ... {'id': 113, 'ip': '10.10.10.16', 'is_blocked': 0} ... ], 'ip')) [{'id': 113, 'ip': '10.10.10.1,10.10.10.16', 'is_blocked': 0}, {'id': 114, 'ip': '10.10.10.2', 'is_blocked': 1}] """ if joiner is None: joiner = lambda items: ",".join(sorted(items)) keyfunc = lambda item: item[key_name] for _, items in groupby(sorted(data, key=keyfunc), keyfunc): result = defaultdict(set) for item in items: for k, v in item.items(): result[k].add(v) yield {k: v.pop() if len(v) == 1 else joiner(v) for k, v in result.items()}
Test case for use in docstring.
But it is ugly and somehow even resource intensive. I would look at whether or not to add GROUP BY
(and array_agg
(PostgreSQL) / GROUP_CONCAT
(MySQL, Oracle)) to the SQL query, since on the part of the DB, such an operation is somehow more convenient.