I have this data :
[
{'name': 'INV/2021/0913', 'invoice_date': datetime.date(2021, 3, 12), 'qty_total': 5.0},
{'name': 'INV/2021/0965', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 6.0},
{'name': 'INV/2021/0966', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 7.0},
{'name': 'INV/2021/0967', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 3.0},
{'name': 'INV/2021/0992', 'invoice_date': datetime.date(2021, 3, 15), 'qty_total': 4.0}
]
As it can be seen the middle 3 dicts have same date.
I want to combine the dictionaries having the same invoice_date and sum up the its qty_total. Set the name attribute to "" for the combined dictionaries. The result should look like this:
[
{'name': 'INV/2021/0913', 'invoice_date': datetime.date(2021, 3, 12), 'qty_total': 5.0},
{'name': '', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 16.0},
{'name': 'INV/2021/0992', 'invoice_date': datetime.date(2021, 3, 15), 'qty_total': 4.0}
]
CodePudding user response:
Consider utilizing a for loop:
import datetime
data = [
{'name': 'INV/2021/0913', 'invoice_date': datetime.date(2021, 3, 12), 'qty_total': 5.0},
{'name': 'INV/2021/0965', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 6.0},
{'name': 'INV/2021/0966', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 7.0},
{'name': 'INV/2021/0967', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 3.0},
{'name': 'INV/2021/0992', 'invoice_date': datetime.date(2021, 3, 15), 'qty_total': 4.0},
]
invoice_date_to_entry = {}
for entry in data:
invoice_date = entry['invoice_date']
if invoice_date not in invoice_date_to_entry:
invoice_date_to_entry[invoice_date] = entry
else:
invoice_date_to_entry[invoice_date]['name'] = ''
invoice_date_to_entry[invoice_date]['qty_total'] = entry['qty_total']
new_data = list(invoice_date_to_entry.values())
for entry in new_data:
print(entry)
Output:
{'name': 'INV/2021/0913', 'invoice_date': datetime.date(2021, 3, 12), 'qty_total': 5.0}
{'name': '', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 16.0}
{'name': 'INV/2021/0992', 'invoice_date': datetime.date(2021, 3, 15), 'qty_total': 4.0}
CodePudding user response:
use itertools.groupby
from datetime import datetime
from itertools import groupby
l = [
{'name': 'INV/2021/0913', 'invoice_date': datetime(2021, 3, 12).date(), 'qty_total': 5.0},
{'name': 'INV/2021/0965', 'invoice_date': datetime(2021, 3, 14).date(), 'qty_total': 6.0},
{'name': 'INV/2021/0966', 'invoice_date': datetime(2021, 3, 14).date(), 'qty_total': 7.0},
{'name': 'INV/2021/0967', 'invoice_date': datetime(2021, 3, 14).date(), 'qty_total': 3.0},
{'name': 'INV/2021/0992', 'invoice_date': datetime(2021, 3, 15).date(), 'qty_total': 4.0}
]
res = []
for k, v in groupby(sorted(l, key=lambda x: x["invoice_date"]), key=lambda x: (x["invoice_date"])):
val = list(v)
res.append(
{"name": " " if len(val)>1 else val[0]["name"], "invoice_date": k, "qty_total": sum(vals["qty_total"] for vals in val)}
)
print(res)
Output
[{'name': 'INV/2021/0913',
'invoice_date': datetime.date(2021, 3, 12),
'qty_total': 5.0},
{'name': ' ', 'invoice_date': datetime.date(2021, 3, 14), 'qty_total': 16.0},
{'name': 'INV/2021/0992',
'invoice_date': datetime.date(2021, 3, 15),
'qty_total': 4.0}]