I have a list with dicts like this:
d = [ {'key1': 1, 'key2': 10, 'key3': 0.75, 'key4':5},
{'key1': 2, 'key2': 20, 'key3': 0.6, 'key4':4},
{'key1': 3, 'key2': 10, 'key3': 0.8, 'key4':8
{'key1': 4, 'key2': 30, 'key3': 0.86, 'key4':2},
{'key1': 5, 'key2': 10, 'key3': 0.9, 'key4':7},
{'key1': 6, 'key2': 20, 'key3': 0.73, 'key4':3},
]
and I want to group the dicts that have the same value in the key2. Like this:
d10= [{'key1': 1, 'key2': 10, 'key3': 0.75, 'key4':5},
{'key1': 3, 'key2': 10, 'key3': 0.8, 'key4':8},
{'key1': 5, 'key2': 10, 'key3': 0.9, 'key4':7} ]
d20= [ {'key1': 2, 'key2': 20, 'key3': 0.6, 'key4':4},
{'key1': 6, 'key2': 20, 'key3': 0.73, 'key4':3} ]
d30=[ {'key1': 4, 'key2': 30, 'key3': 0.86, 'key4':2} ]
Can you help me?
CodePudding user response:
Here is one approach using defaultdict:
from collections import defaultdict
res = defaultdict(list)
for obj in d:
key = obj['key2']
res[key].append(obj)
Output:
defaultdict(list,
{10: [{'key1': 1, 'key2': 10, 'key3': 0.75, 'key4': 5},
{'key1': 3, 'key2': 10, 'key3': 0.8, 'key4': 8},
{'key1': 5, 'key2': 10, 'key3': 0.9, 'key4': 7}],
20: [{'key1': 2, 'key2': 20, 'key3': 0.6, 'key4': 4},
{'key1': 6, 'key2': 20, 'key3': 0.73, 'key4': 3}],
30: [{'key1': 4, 'key2': 30, 'key3': 0.86, 'key4': 2}]})
CodePudding user response:
Using sorted and itertools.groupby. I also use operator.itemgetter as a helper method in place of using a lambda:
from itertools import groupby
from operator import itemgetter
get_key2 = itemgetter('key2')
result = {k: list(g) for k, g in groupby(sorted(d, key=get_key2), get_key2)}
CodePudding user response:
There are already some good answers, but I would also like to present my approach in case it helps:
import itertools
d = [ {'key1': 1, 'key2': 10, 'key3': 0.75, 'key4':5},
{'key1': 2, 'key2': 20, 'key3': 0.6, 'key4':4},
{'key1': 3, 'key2': 10, 'key3': 0.8, 'key4':8},
{'key1': 4, 'key2': 30, 'key3': 0.86, 'key4':2},
{'key1': 5, 'key2': 10, 'key3': 0.9, 'key4':7},
{'key1': 6, 'key2': 20, 'key3': 0.73, 'key4':3},
]
result = {}
for _, e in itertools.groupby(d, lambda s: s["key2"]):
x = [g for g in e]
print(_, x)
if 'd{}'.format(_) not in result:
result['d{}'.format(_)] = x
else:
result['d{}'.format(_)] = x
print(result)
Output:
{'d10': [{'key1': 1, 'key2': 10, 'key3': 0.75, 'key4': 5}, {'key1': 3, 'key2': 10, 'key3': 0.8, 'key4': 8}, {'key1': 5, 'key2': 10, 'key3': 0.9, 'key4': 7}],
'd20': [{'key1': 2, 'key2': 20, 'key3': 0.6, 'key4': 4}, {'key1': 6, 'key2': 20, 'key3': 0.73, 'key4': 3}],
'd30': [{'key1': 4, 'key2': 30, 'key3': 0.86, 'key4': 2}]}
CodePudding user response:
an another approach is:
def groupby(dictionaries, bykey):
keys = {dictionary[bykey] for dictionary in dictionaries}
groups = []
for key in keys:
groups.append([dictionary for dictionary in dictionaries
if dictionary[bykey] == key])
return groups
output:
>>> groupby(d, 'key2')
>>> [
[
{'key1': 1, 'key2': 10, 'key3': 0.75, 'key4': 5},
{'key1': 3, 'key2': 10, 'key3': 0.8, 'key4': 8},
{'key1': 5, 'key2': 10, 'key3': 0.9, 'key4': 7}
],
[
{'key1': 2, 'key2': 20, 'key3': 0.6, 'key4': 4},
{'key1': 6, 'key2': 20, 'key3': 0.73, 'key4': 3}
],
[
{'key1': 4, 'key2': 30, 'key3': 0.86, 'key4': 2}
]
]
