包含重复项的嵌套字典中的求和值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了包含重复项的嵌套字典中的求和值相关的知识,希望对你有一定的参考价值。

我有一个defaultdict(int)的元组(它包含2个内部键),我想只将那些具有相同元组第一元素的内部键的值相加。

例如:

dict = defaultdict(lambda: defaultdict(int))

dict[key][elem_one, elem_two] += 1  # defaultdict format

# The keys (elem1, elem2) and their values (ints) under the first outer key:
(a1, b1) = 1
(a2, b2) = 1
(a2, b1) = 7
(a3, b3) = 4
(a3, b1) = 10

我想将b1b2b3加在一起,无论a在元组的第一个元素中的值如何,并输出一个仅包含b值及其求和值的集合。期望的输出:

{b1 = 18, b2 = 1, b3 = 4}

到目前为止我尝试过的是:

out_set = {k[1]: v for k, v in dict[key].items()}  # k[1] gives me b

这给了我正确的格式,但错误的数字!这不是总结。我有类似的东西:

{b1 = 1, b2 = 1, b3 = 1}

所以我试着改变我的代码如下:

out_set = {k[1]: sum(v) for k, v in dict[key].items()}  # k[1] gives me b

但是我收到以下错误:

TypeError: 'int' object is not iterable

我怎么能纠正这个?

在我的实际代码中,我的defaultdict(int)要大得多。例如,一个键可以包含16个(elem1, elem2)值及其各自的值。我发现当我转换为集合时,它会删除任何重复的elem2(这是所需的),但它似乎采用与elem2相关的随机值,而不是重复elem2s的总和(这是期望的) 。

答案

我建议你使用另一个defaultdict,并利用整数的默认值是0的事实,因此,你将能够添加到一个新声明的(并没有显式初始化)整数,因为它将被隐式初始化为0无论如何。像这样的东西:

import collections

dct = {
    (1, 1): 1,  # This will be overwritten by (1, 1): 7
    (2, 2): 1,
    (1, 1): 7,
    (3, 3): 4,
    (3, 1): 10
}

aux_dict = collections.defaultdict(int)
for key, val in dct.items():
    aux_dict[key[1]] += val
print(aux_dict) 

将输出:

defaultdict(<type 'int'>, {1: 17, 2: 1, 3: 4})

但是,由于元组(和dicts)如何工作,我发现重要的是坚持你不能有两个相同的键。这意味着......

dct = {
    (1, 1): 1,  # This will be overwritten by (1, 1): 7
    (1, 1): 7,
}
print(dct)

......只会输出{(1, 1): 7}。如果你需要保留重复的密钥...不知何故,这是一个不同的问题:这与求和值无关,而是如何在字典中保留“重复”键。我引用副本因为你真的不能有两个相同的键。我们需要找出一种不将这些键视为重复的方法。

我对上面段落的意思是你不会得到b1: 18,因为(a1, b1): 1不在要添加的值的字典中,因为你在代码中有后面的(a1, b1): 7

以上是关于包含重复项的嵌套字典中的求和值的主要内容,如果未能解决你的问题,请参考以下文章

在嵌套字典中求和值

搜索特定值的嵌套字典列表[重复]

将一个嵌套字典中的选择项追加到另一个

具有相同键的(嵌套)字典的 Pythonic 替代方案?

如何使用linq从字典中获取嵌套键值对[重复]

JS:如果沿嵌套字典路径为空,则返回默认值[重复]