在Python中,如何在类似dict的结构中求和耦合值?

在Python中,如何在类似dict的结构中求和耦合值?,python,python-2.7,dictionary,key,tuples,Python,Python 2.7,Dictionary,Key,Tuples,我有一个xlsx,我正在用openpyxl解析它 A列是产品名称,B列是收入,我想将每对产品收入值提取到Adict中。若并没有重复的产品,那个么只需通过适当地映射ws.columns来创建dict即可 问题是,有些(但不是全部)产品有多个条目。对于这些,我需要对有问题的值求和,然后只为这些产品返回一个键(对于其他产品也是如此)。因此,如果我的收入电子表格包含以下内容: 在返回dict之前,我想对香蕉的收入值进行求和。然后期望的结果是: {'Banana': 7.2, 'Apple': 1.7,

我有一个xlsx,我正在用
openpyxl
解析它

A列是产品名称,B列是收入,我想将每对产品收入值提取到A
dict
中。若并没有重复的产品,那个么只需通过适当地映射
ws.columns
来创建dict即可

问题是,有些(但不是全部)产品有多个条目。对于这些,我需要对有问题的值求和,然后只为这些产品返回一个键(对于其他产品也是如此)。因此,如果我的收入电子表格包含以下内容:

在返回dict之前,我想对香蕉的收入值进行求和。然后期望的结果是:

{'Banana': 7.2, 'Apple': 1.7, 'Pear': 6.2, 'Kiwi': 1.2}
如果没有重复项,以下操作正常:

revenue{}
i = 0;
for product in ws.columns[0]:
    revenue[product.value] = ws.columns[1][i].value
    i+=1
但很明显,当它遇到重复项时就会崩溃。我可以尝试使用,它将给出一个结构,我可以从中执行加法并创建最终的
dict

d = MultiDict()
for i in range(len(ws.columns[1])):
        d.add(ws.columns[0][i].value,ws.columns[1][i].value)

这就给我留下了一个
MultiDict
,它本身实际上是一个元组列表,这一切都有点复杂。是否有一种更整洁或标准的库方法来实现相同的密钥多次数据结构?使用
zip()
怎么样?不一定要像迪克特一样。我只需要能够从中创建一个
dict
(然后执行加法)。

假设您可以将数据转换为键值元组列表,则这应该接近您想要的:

list_key_value_tuples = [("A", 1), ("B", 2), ("A", 3)]

d = {}
for key, value in list_key_value_tuples:
    d[key] = d.get(key, 0) + value

> print d
{'A': 4, 'B': 2}

假设您可以将数据转换为键值元组列表,这应该与您想要的接近:

list_key_value_tuples = [("A", 1), ("B", 2), ("A", 3)]

d = {}
for key, value in list_key_value_tuples:
    d[key] = d.get(key, 0) + value

> print d
{'A': 4, 'B': 2}

collections.defaultdict
是为这种类型的用例制作的

>>> 
>>> d = collections.defaultdict(float)
>>> p = [('Kiwi', 1.2), ('Banana', 3.2), ('Pear', 6.2), ('Banana', 2.3), ('Apple', 1.7), ('Banana', 1.7)]
>>> for k,v in p:
    d[k] += v


>>> d
defaultdict(<type 'float'>, {'Kiwi': 1.2, 'Pear': 6.2, 'Banana': 7.2, 'Apple': 1.7})
>>>
>
>>>d=集合.defaultdict(浮点)
>>>p=[('Kiwi',1.2),('Banana',3.2),('Pear',6.2),('Banana',2.3),('Apple',1.7),('Banana',1.7)]
>>>对于p中的k,v:
d[k]+=v
>>>d
defaultdict(,{'Kiwi':1.2,'Pear':6.2,'Banana':7.2,'Apple':1.7})
>>>

集合。defaultdict
是为这种类型的用例制作的

>>> 
>>> d = collections.defaultdict(float)
>>> p = [('Kiwi', 1.2), ('Banana', 3.2), ('Pear', 6.2), ('Banana', 2.3), ('Apple', 1.7), ('Banana', 1.7)]
>>> for k,v in p:
    d[k] += v


>>> d
defaultdict(<type 'float'>, {'Kiwi': 1.2, 'Pear': 6.2, 'Banana': 7.2, 'Apple': 1.7})
>>>
>
>>>d=集合.defaultdict(浮点)
>>>p=[('Kiwi',1.2),('Banana',3.2),('Pear',6.2),('Banana',2.3),('Apple',1.7),('Banana',1.7)]
>>>对于p中的k,v:
d[k]+=v
>>>d
defaultdict(,{'Kiwi':1.2,'Pear':6.2,'Banana':7.2,'Apple':1.7})
>>>

假设第二列的
长度小于第一列;只需在第一列中按值对行进行分组,然后将其余行相加,如下所示:

from itertools import izip_longest, groupby
from operator import itemgetter

rows = izip_longest(ws.columns[0], ws.columns[1], fillvalue=0)

result = dict((k, sum((g[1] for g in v))) for k, v in groupby(rows, itemgetter(0)))

假设第二列的
长度
小于第一列;只需在第一列中按值对行进行分组,然后将其余行相加,如下所示:

from itertools import izip_longest, groupby
from operator import itemgetter

rows = izip_longest(ws.columns[0], ws.columns[1], fillvalue=0)

result = dict((k, sum((g[1] for g in v))) for k, v in groupby(rows, itemgetter(0)))

嗯,假设一个多目录实际上类似于上面的
list\u key\u value
(即一个元组列表),我碰巧用多目录作为
list\u key\u value
运行了您的建议。它导致ValueError:太多的值无法解压缩。因此,我重新处理了值的提取,将它们放入元组列表中,就像您所做的一样,并且成功了。非常好,谢谢你。你可以将d初始化为
defaultdict(int)
来去掉表达式
d.get(key,0)
,没错。在我看来,使用一种或另一种方法是个人喜好的问题——我更喜欢
get
方法,因为它确切地说明了它的功能。考虑到一个MultiDict实际上类似于上面的
list\u key\u值
(即一个元组列表),我碰巧用MutliDict作为
list\u key\u值
运行了您的建议。它导致ValueError:太多的值无法解压缩。因此,我重新处理了值的提取,将它们放入元组列表中,就像您所做的一样,并且成功了。非常好,谢谢你。你可以将d初始化为
defaultdict(int)
来去掉表达式
d.get(key,0)
,没错。在我看来,使用一个或另一个是个人喜好的问题-我更喜欢
get
方法,因为它确切地说明了它的功能。谢谢,我会尝试一下。谢谢,我会尝试一下。列的长度是相等的,但我还是会尝试你的方法。谢谢。如果列长度相等,那就没关系了。上面的代码只有在第一列的长度更大时才会中断。列的长度相等,但我还是会尝试您的方法。谢谢。如果列长度相等,那就没关系了。仅当第一列的长度大于时,上述代码才会中断。