【问题标题】:combining two python dictionaries into one when the net values are not positive [duplicate]当净值不为正时,将两个python字典合二为一[重复]
【发布时间】:2015-04-23 03:42:33
【问题描述】:

我有两个 python 字典,我试图将这些值加在一起。答案在:Is there any pythonic way to combine two dicts (adding values for keys that appear in both)? 让我大部分时间。但是,在某些情况下,净值可能为零或负,但我仍然想要最终字典中的值。尽管 Counters 会接受负值,但它只会在大于零时输出一个值。

例子

from collections import Counter   
A = Counter({'a': 1, 'b': 2, 'c': -3, 'e': 5, 'f': 5})
B = Counter({'b': 3, 'c': 4, 'd': 5, 'e': -5, 'f': -6})
C = A + B
print(C.items())

输出:[('a', 1), ('c', 1), ('b', 5), ('d', 5)]

c = -3 + 4 = 1 是正确的,因此负输入不是问题,但输出中缺少 e:0 和 f:-1

如何执行求和并获得所有值输出?

【问题讨论】:

  • 你需要一个循环遍历唯一的排序组合键

标签: python dictionary


【解决方案1】:

求和会将值降到 0 或更低,是的,如文档所述:

提供了多种数学运算,用于组合 Counter 对象以生成多重集(计数大于零的计数器)。加法和减法通过增加或减少相应元素的计数来组合计数器。交集和并集返回相应计数的最小值和最大值。每个操作都可以接受带符号计数的输入,但输出将排除计数为零或更少的结果。

[...]

  • multiset 方法仅适用于具有正值的用例。输入可能是负数或零,但只创建具有正值的输出。没有类型限制,但是值类型需要支持加减比较。

如果您想将值保留为 0 或更低,则需要使用 Counter.update()。由于这是就地操作,您必须在此处创建一个副本:

>>> from collections import Counter   
>>> A = Counter({'a': 1, 'b': 2, 'c': -3, 'e': 5, 'f': 5})
>>> B = Counter({'b': 3, 'c': 4, 'd': 5, 'e': -5, 'f': -6})
>>> C = A.copy()
>>> C.update(B)
>>> C
Counter({'b': 5, 'd': 5, 'a': 1, 'c': 1, 'e': 0, 'f': -1})

如果保留A 不是目标,您可以直接更新它。

【讨论】:

  • 为什么Counter() 在对负数求和时会这样?这让我感到很意外,而不是我所知道和钦佩的 Python……
  • @Chris_Rands 因为计数器是多组;一个集合,它既可以处理成员资格,也可以计算它是该集合的一部分的次数。 0(或更低)表示它不再是集合的一部分,因此被移除。
  • 谢谢,这是有道理的。下一个想法,在 Python 3.5+ 中,您可以使用 dicts 与 {**A, **B} 组合,但这不适用于 Counter(**A,**B)
  • @Chris_Rands:实际上效果很好,但要考虑到使用该语法时,A 和 B 之间不允许重复键。
【解决方案2】:

比如:

dict((x, a.get(x, 0) + b.get(x, 0)) for x in set(a)|set(b))

示例:

>>> a = {'a':1, 'b':2, 'c':-3, 'e':5, 'f': 5}
>>> b = {'b':3, 'c':4, 'd':5, 'e':-5, 'f': -6}
>>>
>>> dict((x, a.get(x, 0) + b.get(x, 0)) for x in set(a)|set(b))
{'e': 0, 'a': 1, 'f': -1, 'd': 5, 'c': 1, 'b': 5}

【讨论】:

  • 然而,这不会产生一个新的Counter() 对象。
  • 这是必需的吗?据我了解,目标只是将两个字典添加在一起。但事实并非如此。
  • 不需要特别将计数器作为输出。最后,我只是将最终结果输出到文件中。这确实有效。计数器只是添加我在引用帖子中找到的字典的一种方式。谢谢
  • 只是一个后续说明。使用字典方法的处理时间比计数器方法要慢得多。在我正在处理的数据集上,不同之处在于使用计数器需要 1 分钟,而使用字典需要 10 分钟。这些数十亿行表正在处理,因此如果使用字典解决方案产生缓慢的结果,请尝试下面的备用计数器代码。
猜你喜欢
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 2017-10-25
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
相关资源
最近更新 更多