对包含重复项的嵌套字典中的值求和
Sum Values in a Nested Dictionary Containing Duplicates
我有一个 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
我想将 b1
、b2
和 b3
加在一起,而不考虑元组第一个元素中 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
关联的随机值,而不是总和重复的 elem2
s(这是需要的)。
我建议您使用另一个 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})
但是,由于元组(和听写)的工作方式,我发现坚持不能有两个相等的键这一事实很重要。意思是,这...
dct = {
(1, 1): 1, # This will be overwritten by (1, 1): 7
(1, 1): 7,
}
print(dct)
... 只会输出 {(1, 1): 7}
。如果您需要保留重复的键...不知何故,那是一个不同的问题:这与求和值无关,而是与如何在字典中保留 "duplicate" 键有关。我引用 duplicate 因为你真的不能有两个相同的键。我们需要找出一种不将这些键视为重复键的方法。
我在上面的段落中的意思是你不会得到 b1: 18
因为 (a1, b1): 1
不在要添加的值字典中,因为你有 [=19] =] 后面的代码。
我有一个 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
我想将 b1
、b2
和 b3
加在一起,而不考虑元组第一个元素中 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
关联的随机值,而不是总和重复的 elem2
s(这是需要的)。
我建议您使用另一个 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})
但是,由于元组(和听写)的工作方式,我发现坚持不能有两个相等的键这一事实很重要。意思是,这...
dct = {
(1, 1): 1, # This will be overwritten by (1, 1): 7
(1, 1): 7,
}
print(dct)
... 只会输出 {(1, 1): 7}
。如果您需要保留重复的键...不知何故,那是一个不同的问题:这与求和值无关,而是与如何在字典中保留 "duplicate" 键有关。我引用 duplicate 因为你真的不能有两个相同的键。我们需要找出一种不将这些键视为重复键的方法。
我在上面的段落中的意思是你不会得到 b1: 18
因为 (a1, b1): 1
不在要添加的值字典中,因为你有 [=19] =] 后面的代码。