2017-05-29 61 views
0
data = [(0, 0, {'product_id': 6, 'qty': 1.0}), (0, 0, {'product_id': 8, 'qty': 1.0}), (0, 0, {'product_id': 7, 'qty': 2.0}), (0, 0, {'product_id': 6, 'qty': 1.0}), (0, 0, {'product_id': 8, 'qty': 1.0}), (0, 0, {'product_id': 7, 'qty': 2.0})] 

我有这个名单,我想要做的是找到repeted产品ID和总结theire数量,并从列表中删除重复的产品ID elelment找到列表复制和总结

列表的输出应为:

new_data = [(0, 0, {'product_id': 6, 'qty': 2.0}), (0, 0, {'product_id': 8, 'qty': 2.0}), (0, 0, {'product_id': 7, 'qty': 4.0})] 

回答

3

我认为最简单的方法是为您的产品ID构建一个字典(地图),将数据提取到该字典中,然后构建新的数据列表。例如:

from collections import defaultdict 
def mergeQty(data): 
    qtyMap = defaultdict(float) 
    for x, y, product in data: 
    id = product['product_id'] 
    qty = product['qty'] 
    qtyMap[(x, y, id)] += qty 

    return [(x, y, { 'product_id' : id, 'qty' : qty }) for (x, y, id), qty in qtyMap.iteritems()] 

请注意,这不是合并产品,其前两个值不同(在你的榜样,他们都为0的,我们只能在那些什么意思猜的)。

编辑:感谢Azat的defaultdict建议。

编辑:保持未知字段xy完整按照kuro的建议。

+1

怎么样'qtyMap = defaultdict(浮点)'? –

+0

@AzatIbrakov我很幸福没有意识到defaultdict。编辑,谢谢:) –

+1

你的答案适用于给出的样本数据。但是,如果你不把硬编码为0的元组填充为前2个元素,那将会更好。你可以简单地使用'(x,y,id)'作为'qtyMap'的键,并相应地改变列表理解 – kuro

1

一行溶液:

data = [(0, 0, {'product_id': 6, 'qty': 1.0}), (0, 0, {'product_id': 8, 'qty': 1.0}), 
     (0, 0, {'product_id': 7, 'qty': 2.0}), (0, 0, {'product_id': 6, 'qty': 1.0}), 
     (0, 0, {'product_id': 8, 'qty': 1.0}), (0, 0, {'product_id': 7, 'qty': 2.0})] 

import itertools 
import functools 
from operator import itemgetter 

[functools.reduce(lambda x, y: (x[0], x[1], {'product_id': x[2]['product_id'], 'qty': x[2]['qty'] + y[2]['qty']}), y) for _,y in itertools.groupby(sorted(data, key=lambda x: itemgetter('product_id')(itemgetter(2)(x))),key=lambda x: itemgetter('product_id')(itemgetter(2)(x)))] 
+0

不错的一行代码,但很难分解。 –