Reputation: 39
I currently have a list of values which look something like this:
lst = [{'Amount': 13.5, 'Name': 'Amy', 'date': '2022-01-30'},
{'Amount': 15, 'Name': 'Bob', 'date': '2022-01-30'},
{'Amount': 13.5, 'Name': 'Cara', 'date': '2022-01-31'}]
How can I group it by the date?
[{'date': '2022-01-30', 'details': [{'Amount': 13.5, 'Name': 'Amy'}, {'Amount': 15, 'Name': 'Bob'}]},
{'date': '2022-01-31', 'details': [{'Amount': 13.5, 'Name': 'Cara'}]
I have tried something with for loop but it doesnt seem to work for me
final_data = []
for i in lst:
temp_data = {}
if i['date'] not in temp_data:
temp_data['date'] = i['date']
final_data.append(temp_data)
Upvotes: 0
Views: 59
Reputation: 9377
The self-implementing way is using for-loop with adding to the desired structure.
You can also use the module from standard library itertools.groupby
, when the input is sorted (before).
You can adjust the example from docs for your case:
from itertools import groupby
lst = [
{'Amount': 13.5, 'Name': 'Amy', 'date': '2022-01-30'},
{'Amount': 15, 'Name': 'Bob', 'date': '2022-01-30'},
{'Amount': 13.5, 'Name': 'Cara', 'date': '2022-01-31'}
]
keyfunc = lambda x: x['date'] # extracting the key for sort and group
groups = []
uniquekeys = []
data = sorted(lst, key=keyfunc) # required for groupby
for k, g in groupby(data, keyfunc):
groups.append({'date': k, 'details': list(g)}) # Store group iterator as a list
uniquekeys.append(k)
print(groups)
Prints:
[{'date': '2022-01-30', 'details': [{'Amount': 13.5, 'Name': 'Amy', 'date': '2022-01-30'}, {'Amount': 15, 'Name': 'Bob', 'date': '2022-01-30'}]}, {'date': '2022-01-31', 'details': [{'Amount': 13.5, 'Name': 'Cara', 'date': '2022-01-31'}]}]
Since your output in details
is not just a grouped list, but has the key (used for group-by) removed, we need to adjust a bit:
from itertools import groupby
lst = [
{'Amount': 13.5, 'Name': 'Amy', 'date': '2022-01-30'},
{'Amount': 15, 'Name': 'Bob', 'date': '2022-01-30'},
{'Amount': 13.5, 'Name': 'Cara', 'date': '2022-01-31'}
]
keyfunc = lambda x: x['date'] # extracting the key for sort and group
groups = []
data = sorted(lst, key=keyfunc) # required for groupby
for k, g in groupby(data, keyfunc):
# remove the key from grouped list
removed_key = []
for v in list(g):
del v['date']
removed_key.append(v)
# add to groups
groups.append({'date': k, 'details': removed_key})
print(groups)
Prints desired:
[{'date': '2022-01-30', 'details': [{'Amount': 13.5, 'Name': 'Amy'}, {'Amount': 15, 'Name': 'Bob'}]}, {'date': '2022-01-31', 'details': [{'Amount': 13.5, 'Name': 'Cara'}]}]
Upvotes: 0
Reputation: 260380
I would recommend to use a dictionary as output:
from collections import defaultdict
out = defaultdict(list)
for d in lst:
d = d.copy() # avoids mutating the original dictionaries.
out[d.pop('date')].append(d)
dict(out)
output:
{'2022-01-30': [{'Amount': 13.5, 'Name': 'Amy'}, {'Amount': 15, 'Name': 'Bob'}],
'2022-01-31': [{'Amount': 13.5, 'Name': 'Cara'}]}
If you really want your format:
out2 = [{'date': k, 'details': v} for k,v in out.items()]
output:
[{'date': '2022-01-30', 'details': [{'Amount': 13.5, 'Name': 'Amy'}, {'Amount': 15, 'Name': 'Bob'}]},
{'date': '2022-01-31', 'details': [{'Amount': 13.5, 'Name': 'Cara'}]}]
out = {}
for d in lst:
d = d.copy()
date = d.pop('date')
if date not in out:
out[date] = []
out[date].append(d)
out = {}
for d in lst:
d = d.copy()
date = d.pop('date')
if date not in out:
out[date] = {'date': date, 'details': []}
out[date]['details'].append(d)
out = list(out.values())
Upvotes: 1