是否有python化的方法来组合两个句柄(为两个句柄中出现的键添加值)?

时间:2022-03-16 22:08:12

For example I have two dicts:

举个例子,我有两个决定:

Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}

I need a pythonic way of 'combining' two dicts such that the result is:

我需要一种“结合”两个论断的python方法,这样的结果是:

{'a': 1, 'b': 5, 'c': 7, 'd': 5}

That is to say: if a key appears in both dicts, add their values, if it appears in only one dict, keep its value.

也就是说:如果一个键出现在两个命令中,那么添加它们的值,如果只出现在一个命令中,则保持它的值。

18 个解决方案

#1


767  

Use collections.Counter:

使用collections.Counter:

>>> from collections import Counter
>>> A = Counter({'a':1, 'b':2, 'c':3})
>>> B = Counter({'b':3, 'c':4, 'd':5})
>>> A + B
Counter({'c': 7, 'b': 5, 'd': 5, 'a': 1})

Counters are basically a subclass of dict, so you can still do everything else with them you'd normally do with that type, such as iterate over their keys and values.

计数器基本上是命令的一个子类,所以您仍然可以使用该类型来执行其他所有操作,比如迭代它们的键和值。

#2


108  

A more generic solution, which works for non-numeric values as well:

一个更通用的解决方案,也适用于非数字值:

a = {'a': 'foo', 'b':'bar', 'c': 'baz'}
b = {'a': 'spam', 'c':'ham', 'x': 'blah'}

r = dict(a.items() + b.items() +
    [(k, a[k] + b[k]) for k in set(b) & set(a)])

or even more generic:

或者更通用的:

def combine_dicts(a, b, op=operator.add):
    return dict(a.items() + b.items() +
        [(k, op(a[k], b[k])) for k in set(b) & set(a)])

For example:

例如:

>>> a = {'a': 2, 'b':3, 'c':4}
>>> b = {'a': 5, 'c':6, 'x':7}

>>> import operator
>>> print combine_dicts(a, b, operator.mul)
{'a': 10, 'x': 7, 'c': 24, 'b': 3}

#3


59  

>>> A = {'a':1, 'b':2, 'c':3}
>>> B = {'b':3, 'c':4, 'd':5}
>>> c = {x: A.get(x, 0) + B.get(x, 0) for x in set(A).union(B)}
>>> print(c)

{'a': 1, 'c': 7, 'b': 5, 'd': 5}

#4


43  

Intro: There are the (probably) best solutions. But you have to know it and remember it and sometimes you have to hope that your Python version isn't too old or whatever the issue could be.

有(可能)最好的解决方案。但是你必须知道并且记住它,有时候你必须希望你的Python版本不是太旧或者任何问题。

Then there are the most 'hacky' solutions. They are great and short but sometimes are hard to understand, to read and to remember.

然后是最“hacky”的解决方案。他们伟大和短暂,但有时很难理解,阅读和记忆。

There is, though, an alternative which is to to try to reinvent the wheel. - Why reinventing the wheel? - Generally because it's a really good way to learn (and sometimes just because the already-existing tool doesn't do exactly what you would like and/or the way you would like it) and the easiest way if you don't know or don't remember the perfect tool for your problem.

不过,还有另一种选择,那就是尝试重新发明*。-为什么要重新发明*?-通常是因为这是一种很好的学习方式(有时仅仅是因为现有的工具并不能完成您想要的和/或您想要的方式),以及如果您不知道或不记得解决问题的最佳工具,那么这是最简单的方法。

So, I propose to reinvent the wheel of the Counter class from the collections module (partially at least):

因此,我建议从集合模块(至少部分地)重新创建计数器类的*:

class MyDict(dict):
    def __add__(self, oth):
        r = self.copy()

        try:
            for key, val in oth.items():
                if key in r:
                    r[key] += val  # You can custom it here
                else:
                    r[key] = val
        except AttributeError:  # In case oth isn't a dict
            return NotImplemented  # The convention when a case isn't handled

        return r

a = MyDict({'a':1, 'b':2, 'c':3})
b = MyDict({'b':3, 'c':4, 'd':5})

print(a+b)  # Output {'a':1, 'b': 5, 'c': 7, 'd': 5}

There would probably others way to implement that and there are already tools to do that but it's always nice to visualize how things would basically works.

可能还会有其他方法来实现这一点,已经有了一些工具可以做到这一点,但我们总是很好地想象事物是如何运作的。

#5


11  

myDict = {}
for k in itertools.chain(A.keys(), B.keys()):
    myDict[k] = A.get(k, 0)+B.get(k, 0)

#6


11  

The one with no extra imports!

没有额外进口的那个!

Their is a pythonic standard called EAFP(Easier to Ask for Forgiveness than Permission). Below code is based on that python standard.

这是一种叫做EAFP(请求原谅比允许更容易)的python标准。下面的代码基于python标准。

# The A and B dictionaries
A = {'a': 1, 'b': 2, 'c': 3}
B = {'b': 3, 'c': 4, 'd': 5}

# The final dictionary. Will contain the final outputs.
newdict = {}

# Make sure every key of A and B get into the final dictionary 'newdict'.
newdict.update(A)
newdict.update(B)

# Iterate through each key of A.
for i in A.keys():

    # If same key exist on B, its values from A and B will add together and
    # get included in the final dictionary 'newdict'.
    try:
        addition = A[i] + B[i]
        newdict[i] = addition

    # If current key does not exist in dictionary B, it will give a KeyError,
    # catch it and continue looping.
    except KeyError:
        continue

EDIT: thanks to jerzyk for his improvement suggestions.

编辑:感谢jerzyk提出的改进建议。

#7


8  

Definitely summing the Counter()s is the most pythonic way to go in such cases but only if it results in a positive value. Here is an example and as you can see there is no c in result after negating the c's value in B dictionary.

显然,在这种情况下,对Counter()s求和是最符合python的方法,但前提是它会产生一个正值。这里有一个例子,您可以看到,在否定了B字典中的c值之后,结果没有c。

In [1]: from collections import Counter

In [2]: A = Counter({'a':1, 'b':2, 'c':3})

In [3]: B = Counter({'b':3, 'c':-4, 'd':5})

In [4]: A + B
Out[4]: Counter({'d': 5, 'b': 5, 'a': 1})

That's because Counters were primarily designed to work with positive integers to represent running counts (negative count is meaningless). But to help with those use cases,python documents the minimum range and type restrictions as follows:

这是因为计数器主要设计为使用正整数来表示运行计数(负计数没有意义)。但是为了帮助这些用例,python记录了以下的最小范围和类型限制:

  • The Counter class itself is a dictionary subclass with no restrictions on its keys and values. The values are intended to be numbers representing counts, but you could store anything in the value field.
  • 计数器类本身是一个字典子类,其键和值没有任何限制。这些值是表示计数的数字,但是您可以在value字段中存储任何内容。
  • The most_common() method requires only that the values be orderable.
  • most_common()方法只要求值是有序的。
  • For in-place operations such as c[key] += 1, the value type need only support addition and subtraction. So fractions, floats, and decimals would work and negative values are supported. The same is also true for update() and subtract() which allow negative and zero values for both inputs and outputs.
  • 对于像c[key] += 1这样的就地操作,值类型只需要支持加减法。所以分数,浮点数和小数都是有效的,负值是受支持的。update()和subtract()也是如此,它们允许输入和输出都为负数和零。
  • The multiset methods are designed only for use cases with positive values. The inputs may be negative or zero, but only outputs with positive values are created. There are no type restrictions, but the value type needs to support addition, subtraction, and comparison.
  • 多集方法只设计用于具有正值的用例。输入可能是负数或零,但只创建具有正值的输出。没有类型限制,但是值类型需要支持添加、减法和比较。
  • The elements() method requires integer counts. It ignores zero and negative counts.
  • 元素()方法需要整数计数。它忽略了零和负的计数。

So for getting around that problem after summing your Counter you can use Counter.update in order to get the desire output. It works like dict.update() but adds counts instead of replacing them.

为了解决这个问题你可以使用计数器。更新以获得期望输出。它的工作方式类似于dict.update(),但是添加计数而不是替换它们。

In [24]: A.update(B)

In [25]: A
Out[25]: Counter({'d': 5, 'b': 5, 'a': 1, 'c': -1})

#8


7  

import itertools
import collections

dictA = {'a':1, 'b':2, 'c':3}
dictB = {'b':3, 'c':4, 'd':5}

new_dict = collections.defaultdict(int)
for k, v in itertools.chain(dictA.iteritems(), dictB.iteritems()):
    new_dict[k] += v

print dict(new_dict)

# OUTPUT
{'a': 1, 'c': 7, 'b': 5, 'd': 5}

OR

Alternative you can use Counter as @Martijn has mentioned above.

您可以使用Counter作为上面提到的@Martijn。

#9


6  

For a more generic and extensible way check mergedict. It uses singledispatch and can merge values based on its types.

要获得更通用和可扩展的方法,请检查mergedict。它使用singledispatch并根据其类型合并值。

Example:

例子:

from mergedict import MergeDict

class SumDict(MergeDict):
    @MergeDict.dispatch(int)
    def merge_int(this, other):
        return this + other

d2 = SumDict({'a': 1, 'b': 'one'})
d2.merge({'a':2, 'b': 'two'})

assert d2 == {'a': 3, 'b': 'two'}

#10


3  

Additionally, please note a.update( b ) is 2x faster than a + b

另外,请注意。更新(b)比a + b快2x

from collections import Counter
a = Counter({'menu': 20, 'good': 15, 'happy': 10, 'bar': 5})
b = Counter({'menu': 1, 'good': 1, 'bar': 3})

%timeit a + b;
## 100000 loops, best of 3: 8.62 µs per loop
## The slowest run took 4.04 times longer than the fastest. This could mean that an intermediate result is being cached.

%timeit a.update(b)
## 100000 loops, best of 3: 4.51 µs per loop

#11


3  

From python 3.5

In this version you can do so:

在本版本中,您可以这样做:

a = {'a': 1, 'b': 2, 'c': 3}
b = {'b': 3, 'c': 4, 'd': 5}
c = {**a, **b}

>>> c
{'a': 1, 'b': 3, 'c': 4, 'd': 5}

Another way

dic1 = {'one':1,'two':2}
dic2 = {'three':3,'four':4}

dic1U2 = {}
for i in dic1.keys():
    dic1U2[i] = dic1[i]

for i in dic2.keys():
    dic1U2[i] = dic2[i]

print(dic1U2)

output:

输出:

{'one': 1, 'two': 2, 'three': 3, 'four': 4}

And ... another way eay to read

a = {'a': 1, 'b': 2, 'c': 3}
b = {'b': 3, 'c': 4, 'd': 5}

for eachkey in b:
    a[eachkey] = b[eachkey]

print(a)

output:

输出:

{'a': 1, 'b': 3, 'c': 4, 'd': 5}

#12


2  

def merge_with(f, xs, ys):
    xs = a_copy_of(xs) # dict(xs), maybe generalizable?
    for (y, v) in ys.iteritems():
        xs[y] = v if y not in xs else f(xs[x], v)

merge_with((lambda x, y: x + y), A, B)

You could easily generalize this:

你可以很容易地概括这一点:

def merge_dicts(f, *dicts):
    result = {}
    for d in dicts:
        for (k, v) in d.iteritems():
            result[k] = v if k not in result else f(result[k], v)

Then it can take any number of dicts.

然后它可以接受任意数量的口授。

#13


2  

This is a simple solution for merging two dictionaries where += can be applied to the values, it has to iterate over a dictionary only once, I'm surprised no one has suggested this

这是一个合并两个字典的简单解决方案,其中+=可以应用于值,它只需要在一个字典上迭代一次,我很惊讶没有人建议这样做

a = {'a':1, 'b':2, 'c':3}

dicts = [{'b':3, 'c':4, 'd':5},
         {'c':9, 'a':9, 'd':9}]

def merge_dicts(merged,mergedfrom):
    for k,v in mergedfrom.items():
        if k in merged:
            merged[k] += v
        else:
            merged[k] = v
    return merged

for dct in dicts:
    a = merge_dicts(a,dct)
print (a)
#{'c': 16, 'b': 5, 'd': 14, 'a': 10}

#14


2  

Merging three dicts a,b,c in a single line without any other modules or libs

合并三个命令a、b、c在一行中,不包含任何其他模块或libs

If we have the three dicts

如果我们有三个结论

a = {"a":9}
b = {"b":7}
c = {'b': 2, 'd': 90}

Merge all with a single line and return a dict object using

合并所有与单一行,并返回一个使用的dict对象

c = dict(a.items() + b.items() + c.items())

Returning

返回

{'a': 9, 'b': 2, 'd': 90}

#15


1  

This solution is easy to use, it is used as a normal dictionary, but you can use the sum function.

这个解决方案很容易使用,它作为一个普通的字典使用,但是您可以使用sum函数。

class SumDict(dict):
    def __add__(self, y):
        return {x: self.get(x, 0) + y.get(x, 0) for x in set(self).union(y)}

A = SumDict({'a': 1, 'c': 2})
B = SumDict({'b': 3, 'c': 4})  # Also works: B = {'b': 3, 'c': 4}
print(A + B)  # OUTPUT {'a': 1, 'b': 3, 'c': 6}

#16


0  

The above solutions are great for the scenario where you have a small number of Counters. If you have a big list of them though, something like this is much nicer:

上面的解决方案对于只有少量计数器的场景来说是很好的。如果你有一个大的列表,像这样的东西会更好:

from collections import Counter

A = Counter({'a':1, 'b':2, 'c':3})
B = Counter({'b':3, 'c':4, 'd':5}) 
C = Counter({'a': 5, 'e':3})
list_of_counts = [A, B, C]

total = sum(list_of_counts, Counter())

print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})

The above solution is essentially summing the Counters by:

上述解本质上是通过:

total = Counter()
for count in list_of_counts:
    total += count
print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})

This does the same thing but I think it always helps to see what it is effectively doing underneath.

这是一样的,但我认为它总是有助于看到它实际上在下面做什么。

#17


0  

What about:

是什么:

def dict_merge_and_sum( d1, d2 ):
    ret = d1
    ret.update({ k:v + d2[k] for k,v in d1.items() if k in d2 })
    ret.update({ k:v for k,v in d2.items() if k not in d1 })
    return ret

A = {'a': 1, 'b': 2, 'c': 3}
B = {'b': 3, 'c': 4, 'd': 5}

print( dict_merge_and_sum( A, B ) )

Output:

输出:

{'d': 5, 'a': 1, 'c': 7, 'b': 5}

#18


-2  

The best to use is dict():

最好使用的是dict():

A = {'a':1, 'b':2, 'c':3}
B = {'b':3, 'c':4, 'd':5}
Merged = dict(A, **B)
Merged == {'a':1, 'b':3, 'c':3, 'd':5}

#1


767  

Use collections.Counter:

使用collections.Counter:

>>> from collections import Counter
>>> A = Counter({'a':1, 'b':2, 'c':3})
>>> B = Counter({'b':3, 'c':4, 'd':5})
>>> A + B
Counter({'c': 7, 'b': 5, 'd': 5, 'a': 1})

Counters are basically a subclass of dict, so you can still do everything else with them you'd normally do with that type, such as iterate over their keys and values.

计数器基本上是命令的一个子类,所以您仍然可以使用该类型来执行其他所有操作,比如迭代它们的键和值。

#2


108  

A more generic solution, which works for non-numeric values as well:

一个更通用的解决方案,也适用于非数字值:

a = {'a': 'foo', 'b':'bar', 'c': 'baz'}
b = {'a': 'spam', 'c':'ham', 'x': 'blah'}

r = dict(a.items() + b.items() +
    [(k, a[k] + b[k]) for k in set(b) & set(a)])

or even more generic:

或者更通用的:

def combine_dicts(a, b, op=operator.add):
    return dict(a.items() + b.items() +
        [(k, op(a[k], b[k])) for k in set(b) & set(a)])

For example:

例如:

>>> a = {'a': 2, 'b':3, 'c':4}
>>> b = {'a': 5, 'c':6, 'x':7}

>>> import operator
>>> print combine_dicts(a, b, operator.mul)
{'a': 10, 'x': 7, 'c': 24, 'b': 3}

#3


59  

>>> A = {'a':1, 'b':2, 'c':3}
>>> B = {'b':3, 'c':4, 'd':5}
>>> c = {x: A.get(x, 0) + B.get(x, 0) for x in set(A).union(B)}
>>> print(c)

{'a': 1, 'c': 7, 'b': 5, 'd': 5}

#4


43  

Intro: There are the (probably) best solutions. But you have to know it and remember it and sometimes you have to hope that your Python version isn't too old or whatever the issue could be.

有(可能)最好的解决方案。但是你必须知道并且记住它,有时候你必须希望你的Python版本不是太旧或者任何问题。

Then there are the most 'hacky' solutions. They are great and short but sometimes are hard to understand, to read and to remember.

然后是最“hacky”的解决方案。他们伟大和短暂,但有时很难理解,阅读和记忆。

There is, though, an alternative which is to to try to reinvent the wheel. - Why reinventing the wheel? - Generally because it's a really good way to learn (and sometimes just because the already-existing tool doesn't do exactly what you would like and/or the way you would like it) and the easiest way if you don't know or don't remember the perfect tool for your problem.

不过,还有另一种选择,那就是尝试重新发明*。-为什么要重新发明*?-通常是因为这是一种很好的学习方式(有时仅仅是因为现有的工具并不能完成您想要的和/或您想要的方式),以及如果您不知道或不记得解决问题的最佳工具,那么这是最简单的方法。

So, I propose to reinvent the wheel of the Counter class from the collections module (partially at least):

因此,我建议从集合模块(至少部分地)重新创建计数器类的*:

class MyDict(dict):
    def __add__(self, oth):
        r = self.copy()

        try:
            for key, val in oth.items():
                if key in r:
                    r[key] += val  # You can custom it here
                else:
                    r[key] = val
        except AttributeError:  # In case oth isn't a dict
            return NotImplemented  # The convention when a case isn't handled

        return r

a = MyDict({'a':1, 'b':2, 'c':3})
b = MyDict({'b':3, 'c':4, 'd':5})

print(a+b)  # Output {'a':1, 'b': 5, 'c': 7, 'd': 5}

There would probably others way to implement that and there are already tools to do that but it's always nice to visualize how things would basically works.

可能还会有其他方法来实现这一点,已经有了一些工具可以做到这一点,但我们总是很好地想象事物是如何运作的。

#5


11  

myDict = {}
for k in itertools.chain(A.keys(), B.keys()):
    myDict[k] = A.get(k, 0)+B.get(k, 0)

#6


11  

The one with no extra imports!

没有额外进口的那个!

Their is a pythonic standard called EAFP(Easier to Ask for Forgiveness than Permission). Below code is based on that python standard.

这是一种叫做EAFP(请求原谅比允许更容易)的python标准。下面的代码基于python标准。

# The A and B dictionaries
A = {'a': 1, 'b': 2, 'c': 3}
B = {'b': 3, 'c': 4, 'd': 5}

# The final dictionary. Will contain the final outputs.
newdict = {}

# Make sure every key of A and B get into the final dictionary 'newdict'.
newdict.update(A)
newdict.update(B)

# Iterate through each key of A.
for i in A.keys():

    # If same key exist on B, its values from A and B will add together and
    # get included in the final dictionary 'newdict'.
    try:
        addition = A[i] + B[i]
        newdict[i] = addition

    # If current key does not exist in dictionary B, it will give a KeyError,
    # catch it and continue looping.
    except KeyError:
        continue

EDIT: thanks to jerzyk for his improvement suggestions.

编辑:感谢jerzyk提出的改进建议。

#7


8  

Definitely summing the Counter()s is the most pythonic way to go in such cases but only if it results in a positive value. Here is an example and as you can see there is no c in result after negating the c's value in B dictionary.

显然,在这种情况下,对Counter()s求和是最符合python的方法,但前提是它会产生一个正值。这里有一个例子,您可以看到,在否定了B字典中的c值之后,结果没有c。

In [1]: from collections import Counter

In [2]: A = Counter({'a':1, 'b':2, 'c':3})

In [3]: B = Counter({'b':3, 'c':-4, 'd':5})

In [4]: A + B
Out[4]: Counter({'d': 5, 'b': 5, 'a': 1})

That's because Counters were primarily designed to work with positive integers to represent running counts (negative count is meaningless). But to help with those use cases,python documents the minimum range and type restrictions as follows:

这是因为计数器主要设计为使用正整数来表示运行计数(负计数没有意义)。但是为了帮助这些用例,python记录了以下的最小范围和类型限制:

  • The Counter class itself is a dictionary subclass with no restrictions on its keys and values. The values are intended to be numbers representing counts, but you could store anything in the value field.
  • 计数器类本身是一个字典子类,其键和值没有任何限制。这些值是表示计数的数字,但是您可以在value字段中存储任何内容。
  • The most_common() method requires only that the values be orderable.
  • most_common()方法只要求值是有序的。
  • For in-place operations such as c[key] += 1, the value type need only support addition and subtraction. So fractions, floats, and decimals would work and negative values are supported. The same is also true for update() and subtract() which allow negative and zero values for both inputs and outputs.
  • 对于像c[key] += 1这样的就地操作,值类型只需要支持加减法。所以分数,浮点数和小数都是有效的,负值是受支持的。update()和subtract()也是如此,它们允许输入和输出都为负数和零。
  • The multiset methods are designed only for use cases with positive values. The inputs may be negative or zero, but only outputs with positive values are created. There are no type restrictions, but the value type needs to support addition, subtraction, and comparison.
  • 多集方法只设计用于具有正值的用例。输入可能是负数或零,但只创建具有正值的输出。没有类型限制,但是值类型需要支持添加、减法和比较。
  • The elements() method requires integer counts. It ignores zero and negative counts.
  • 元素()方法需要整数计数。它忽略了零和负的计数。

So for getting around that problem after summing your Counter you can use Counter.update in order to get the desire output. It works like dict.update() but adds counts instead of replacing them.

为了解决这个问题你可以使用计数器。更新以获得期望输出。它的工作方式类似于dict.update(),但是添加计数而不是替换它们。

In [24]: A.update(B)

In [25]: A
Out[25]: Counter({'d': 5, 'b': 5, 'a': 1, 'c': -1})

#8


7  

import itertools
import collections

dictA = {'a':1, 'b':2, 'c':3}
dictB = {'b':3, 'c':4, 'd':5}

new_dict = collections.defaultdict(int)
for k, v in itertools.chain(dictA.iteritems(), dictB.iteritems()):
    new_dict[k] += v

print dict(new_dict)

# OUTPUT
{'a': 1, 'c': 7, 'b': 5, 'd': 5}

OR

Alternative you can use Counter as @Martijn has mentioned above.

您可以使用Counter作为上面提到的@Martijn。

#9


6  

For a more generic and extensible way check mergedict. It uses singledispatch and can merge values based on its types.

要获得更通用和可扩展的方法,请检查mergedict。它使用singledispatch并根据其类型合并值。

Example:

例子:

from mergedict import MergeDict

class SumDict(MergeDict):
    @MergeDict.dispatch(int)
    def merge_int(this, other):
        return this + other

d2 = SumDict({'a': 1, 'b': 'one'})
d2.merge({'a':2, 'b': 'two'})

assert d2 == {'a': 3, 'b': 'two'}

#10


3  

Additionally, please note a.update( b ) is 2x faster than a + b

另外,请注意。更新(b)比a + b快2x

from collections import Counter
a = Counter({'menu': 20, 'good': 15, 'happy': 10, 'bar': 5})
b = Counter({'menu': 1, 'good': 1, 'bar': 3})

%timeit a + b;
## 100000 loops, best of 3: 8.62 µs per loop
## The slowest run took 4.04 times longer than the fastest. This could mean that an intermediate result is being cached.

%timeit a.update(b)
## 100000 loops, best of 3: 4.51 µs per loop

#11


3  

From python 3.5

In this version you can do so:

在本版本中,您可以这样做:

a = {'a': 1, 'b': 2, 'c': 3}
b = {'b': 3, 'c': 4, 'd': 5}
c = {**a, **b}

>>> c
{'a': 1, 'b': 3, 'c': 4, 'd': 5}

Another way

dic1 = {'one':1,'two':2}
dic2 = {'three':3,'four':4}

dic1U2 = {}
for i in dic1.keys():
    dic1U2[i] = dic1[i]

for i in dic2.keys():
    dic1U2[i] = dic2[i]

print(dic1U2)

output:

输出:

{'one': 1, 'two': 2, 'three': 3, 'four': 4}

And ... another way eay to read

a = {'a': 1, 'b': 2, 'c': 3}
b = {'b': 3, 'c': 4, 'd': 5}

for eachkey in b:
    a[eachkey] = b[eachkey]

print(a)

output:

输出:

{'a': 1, 'b': 3, 'c': 4, 'd': 5}

#12


2  

def merge_with(f, xs, ys):
    xs = a_copy_of(xs) # dict(xs), maybe generalizable?
    for (y, v) in ys.iteritems():
        xs[y] = v if y not in xs else f(xs[x], v)

merge_with((lambda x, y: x + y), A, B)

You could easily generalize this:

你可以很容易地概括这一点:

def merge_dicts(f, *dicts):
    result = {}
    for d in dicts:
        for (k, v) in d.iteritems():
            result[k] = v if k not in result else f(result[k], v)

Then it can take any number of dicts.

然后它可以接受任意数量的口授。

#13


2  

This is a simple solution for merging two dictionaries where += can be applied to the values, it has to iterate over a dictionary only once, I'm surprised no one has suggested this

这是一个合并两个字典的简单解决方案,其中+=可以应用于值,它只需要在一个字典上迭代一次,我很惊讶没有人建议这样做

a = {'a':1, 'b':2, 'c':3}

dicts = [{'b':3, 'c':4, 'd':5},
         {'c':9, 'a':9, 'd':9}]

def merge_dicts(merged,mergedfrom):
    for k,v in mergedfrom.items():
        if k in merged:
            merged[k] += v
        else:
            merged[k] = v
    return merged

for dct in dicts:
    a = merge_dicts(a,dct)
print (a)
#{'c': 16, 'b': 5, 'd': 14, 'a': 10}

#14


2  

Merging three dicts a,b,c in a single line without any other modules or libs

合并三个命令a、b、c在一行中,不包含任何其他模块或libs

If we have the three dicts

如果我们有三个结论

a = {"a":9}
b = {"b":7}
c = {'b': 2, 'd': 90}

Merge all with a single line and return a dict object using

合并所有与单一行,并返回一个使用的dict对象

c = dict(a.items() + b.items() + c.items())

Returning

返回

{'a': 9, 'b': 2, 'd': 90}

#15


1  

This solution is easy to use, it is used as a normal dictionary, but you can use the sum function.

这个解决方案很容易使用,它作为一个普通的字典使用,但是您可以使用sum函数。

class SumDict(dict):
    def __add__(self, y):
        return {x: self.get(x, 0) + y.get(x, 0) for x in set(self).union(y)}

A = SumDict({'a': 1, 'c': 2})
B = SumDict({'b': 3, 'c': 4})  # Also works: B = {'b': 3, 'c': 4}
print(A + B)  # OUTPUT {'a': 1, 'b': 3, 'c': 6}

#16


0  

The above solutions are great for the scenario where you have a small number of Counters. If you have a big list of them though, something like this is much nicer:

上面的解决方案对于只有少量计数器的场景来说是很好的。如果你有一个大的列表,像这样的东西会更好:

from collections import Counter

A = Counter({'a':1, 'b':2, 'c':3})
B = Counter({'b':3, 'c':4, 'd':5}) 
C = Counter({'a': 5, 'e':3})
list_of_counts = [A, B, C]

total = sum(list_of_counts, Counter())

print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})

The above solution is essentially summing the Counters by:

上述解本质上是通过:

total = Counter()
for count in list_of_counts:
    total += count
print(total)
# Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3})

This does the same thing but I think it always helps to see what it is effectively doing underneath.

这是一样的,但我认为它总是有助于看到它实际上在下面做什么。

#17


0  

What about:

是什么:

def dict_merge_and_sum( d1, d2 ):
    ret = d1
    ret.update({ k:v + d2[k] for k,v in d1.items() if k in d2 })
    ret.update({ k:v for k,v in d2.items() if k not in d1 })
    return ret

A = {'a': 1, 'b': 2, 'c': 3}
B = {'b': 3, 'c': 4, 'd': 5}

print( dict_merge_and_sum( A, B ) )

Output:

输出:

{'d': 5, 'a': 1, 'c': 7, 'b': 5}

#18


-2  

The best to use is dict():

最好使用的是dict():

A = {'a':1, 'b':2, 'c':3}
B = {'b':3, 'c':4, 'd':5}
Merged = dict(A, **B)
Merged == {'a':1, 'b':3, 'c':3, 'd':5}