我有一个动态字典,每次都不相同,我想根据多个键将这个字典列表归为一组,一次为一个键,最后一次使用的键附加为sum float&int值。每次使用多键进行分组时都会进行分组,但是在分组的最后一次迭代中,我得到的形式是没有和的最终数据。
为了解释我在这里想要做的是一份字典示例列表(此示例不是静态的,字典的键/值对可能会更改):
[{'invoice_num': 'INV/2019/0012 ', 'tax_id': 'Tax 15.00%S', 'vat': False, 'total_amount': 805.0, 'fiscal_position_id': False, 'date': '2019-12-05', 'amount_exclude': 700.0, 'desc': '[AT] Air Flight', 'partner_id': 'Agrolait', 'amount_tax': 105.0, 'record_type': 'sale'}, {'invoice_num': 'INV/2019/0011 ', 'tax_id': 'Tax 15.00%S', 'vat': False, 'total_amount': 805.0, 'fiscal_position_id': False, 'date': '2019-12-05', 'amount_exclude': 700.0, 'desc': '[AT] Air Flight', 'partner_id': 'Agrolait', 'amount_tax': 105.0, 'record_type': 'sale'}, {'invoice_num': 'BILL/2019/0007 ', 'tax_id': 'Tax 15.00% P', 'vat': False, 'total_amount': 51750.0, 'fiscal_position_id': False, 'date': '2019-12-05', 'amount_exclude': 45000.0, 'desc': '[CONS_DEL02] Little server', 'partner_id': "Administrator, Pieter Parter's Farm", 'amount_tax': 6750.0, 'record_type': 'purchase'}, {'invoice_num': 'BILL/2019/0006 ', 'tax_id': 'Tax 15.00% P', 'vat': False, 'total_amount': 5749.99, 'fiscal_position_id': False, 'date': '2019-12-05', 'amount_exclude': 4999.99, 'desc': "Coffee Machine with huge 'employee's performances boosting perk'", 'partner_id': 'ASUSTeK', 'amount_tax': 750.0, 'record_type': 'purchase'}, {'invoice_num': 'BILL/2019/0002 ', 'tax_id': 'Tax 15.00% P', 'vat': False, 'total_amount': 5749.99, 'fiscal_position_id': False, 'date': '2019-11-15', 'amount_exclude': 4999.99, 'desc': "Coffee Machine with huge 'employee's performances boosting perk'", 'partner_id': 'ASUSTeK', 'amount_tax': 750.0, 'record_type': 'purchase'}]
我想分组:
['record_type', 'tax_id','partner_id']
因此,在第一组(按record_type)中,我希望将数据分组以便仅对值求和,然后在第二组(按record_type和tax_id)中,我要获取具有float&int值之和的值。第三组(按'record_type'&'tax_id'&'partner_id')我想要获取没有总和的记录,然后将其插入到xls文件中。
最终代表将是:
我试图一次将项目分组一次,但是我不能将具有相同元素的数据分组并在表中显示最后一项:
item_data = []
for item in group_by:
final_data = [(a, list(b)) for a, b in
itertools.groupby([i.items() for i in records_read], key=lambda x: dict(x)[item])]
new_final_data = [
{i[0][0]: sum(c[-1] for c in i if isinstance(c[-1], float) or isinstance(c[-1], int)) if i[0][0] != item else
i[0][-1] for i in
zip(*b)} for a, b in final_data]
item_data.append(new_final_data)
答案 0 :(得分:1)
此脚本根据fields
列表打印树:
data = [{'invoice_num': 'INV/2019/0012 ', 'tax_id': 'Tax 15.00%S', 'vat': 'Undefined', 'total_amount': 805.0, 'fiscal_position_id': 'Undefined', 'date': '2019-12-05', 'amount_exclude': 700.0, 'desc': '[AT] Air Flight', 'partner_id': 'Agrolait', 'amount_tax': 105.0, 'record_type': 'sale'}, {'invoice_num': 'INV/2019/0011 ', 'tax_id': 'Tax 15.00%S', 'vat': 'Undefined', 'total_amount': 805.0, 'fiscal_position_id': 'Undefined', 'date': '2019-12-05', 'amount_exclude': 700.0, 'desc': '[AT] Air Flight', 'partner_id': 'Agrolait', 'amount_tax': 105.0, 'record_type': 'sale'}, {'invoice_num': 'BILL/2019/0007 ', 'tax_id': 'Tax 15.00% P', 'vat': 'Undefined', 'total_amount': 51750.0, 'fiscal_position_id': 'Undefined', 'date': '2019-12-05', 'amount_exclude': 45000.0, 'desc': '[CONS_DEL02] Little server', 'partner_id': "Administrator, Pieter Parter's Farm", 'amount_tax': 6750.0, 'record_type': 'purchase'}, {'invoice_num': 'BILL/2019/0006 ', 'tax_id': 'Tax 15.00% P', 'vat': 'Undefined', 'total_amount': 5749.99, 'fiscal_position_id': 'Undefined', 'date': '2019-12-05', 'amount_exclude': 4999.99, 'desc': "Coffee Machine with huge 'employee's performances boosting perk'", 'partner_id': 'ASUSTeK', 'amount_tax': 750.0, 'record_type': 'purchase'}, {'invoice_num': 'BILL/2019/0002 ', 'tax_id': 'Tax 15.00% P', 'vat': 'Undefined', 'total_amount': 5749.99, 'fiscal_position_id': 'Undefined', 'date': '2019-11-15', 'amount_exclude': 4999.99, 'desc': "Coffee Machine with huge 'employee's performances boosting perk'", 'partner_id': 'ASUSTeK', 'amount_tax': 750.0, 'record_type': 'purchase'}]
fields = ['record_type', 'tax_id', 'partner_id', 'invoice_num']
from itertools import groupby
from operator import itemgetter
def group_by_fields(data, *fields):
f = itemgetter(*fields)
for v, g in groupby(sorted(data, key=f), f):
g = list(g)
float_keys = []
for item in g:
float_keys.extend(
[key for key in item if isinstance(item[key], float) or isinstance(item[key], int)])
float_keys = list(set(float_keys))
yield (v,) if isinstance(v, str) else v, [sum(i[k] for i in g) for k in float_keys]
def print_tree(data, *fields):
rv = []
for i in range(1, len(fields)+1):
rv.extend(group_by_fields(data, *fields[:i]))
for v, g in groupby(sorted(rv, key=lambda k: (k[0], len(k[0])) ), lambda k: (k[0], len(k[0])) ):
print('{:<60}'.format( (' ' * (v[1] * 4)) + v[0][-1]), end=' ')
for item in g:
print('{:<10.2f} {:<10.2f} {:<10.2f} '.format(*item[1][0:]))
print_tree(data, *fields)
打印:
purchase 63249.98 54999.98 8250.00
Tax 15.00% P 63249.98 54999.98 8250.00
ASUSTeK 11499.98 9999.98 1500.00
BILL/2019/0002 5749.99 4999.99 750.00
BILL/2019/0006 5749.99 4999.99 750.00
Administrator, Pieter Parter's Farm 51750.00 45000.00 6750.00
BILL/2019/0007 51750.00 45000.00 6750.00
sale 1610.00 1400.00 210.00
Tax 15.00%S 1610.00 1400.00 210.00
Agrolait 1610.00 1400.00 210.00
INV/2019/0011 805.00 700.00 105.00
INV/2019/0012 805.00 700.00 105.00