合并字典而不覆盖值

2023-12-04

这似乎是一个简单的任务:

我正在尝试合并两个字典而不覆盖值但附加。

a = {1: [(1,1)],2: [(2,2),(3,3)],3: [(4,4)]} 
b = {3: [(5,5)], 4: [(6,6)]}

元组数量 a = 4,元组数量 b = 2

这就是为什么我单独列出这些选项,因为它们会覆盖:

all = dict(a.items() + b.items()) 
all = dict(a, **b)
all = a.update([b])

以下解决方案工作得很好,但它还会将值附加到我的原始字典 a 中:

all = {}

for k in a.keys():
    if k in all:
        all[k].append(a[k])
    else:
        all[k] = a[k]


for k in b.keys():
    if k in all:
        all[k].append(b[k])
    else:
        all[k] = b[k]

Output =

a = {1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), **[(5, 5)]**]}
b = {3: [(5, 5)], 4: [(6, 6)]}
c = {1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), [(5, 5)]], 4: [(6, 6)]}

元组数 a =5 !!!!!,元组数 b = 2(正确),元组数 all = 6(正确)

它附加了元组[(5,5)]从 b 到 a。我不知道为什么会发生这种情况,因为我正在编码的只是将所有内容写入完整的字典“all”中。

谁能告诉我它到底在哪里改变 dict(a) ??????

非常欢迎任何帮助。


Use .extend代替.append用于将列表合并在一起。

>>> example = [1, 2, 3]
>>> example.append([4, 5])
>>> example
[1, 2, 3, [4, 5]]
>>> example.extend([6, 7])
>>> example
[1, 2, 3, [4, 5], 6, 7]

此外,您可以循环遍历两者的键和值a and b一起使用itertools.chain:

from itertools import chain
all = {}
for k, v in chain(a.iteritems(), b.iteritems()):
    all.setdefault(k, []).extend(v)

.setdefault()查找一个键,如果尚不存在则将其设置为默认值。或者你可以使用collections.defaultdict隐式地做同样的事情。

outputs:

>>> a
{1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4)]}
>>> b
{3: [(5,5)], 4: [(6,6)]}
>>> all
{1: [(1, 1)], 2: [(2, 2), (3, 3)], 3: [(4, 4), (5, 5)], 4: [(6, 6)]}

请注意,因为我们现在首先为每个键创建一个干净的新列表,然后扩展您的原始列表a不受影响。在您的代码中,您不会创建列表的副本;而是创建列表的副本。相反,你复制了参考列表。最终双方alladict 值指向相同的列表,并且在这些列表上使用追加会导致更改在两个位置都可见。

使用简单变量而不是字典很容易证明这一点:

>>> foo = [1, 2, 3]
>>> bar = foo
>>> bar
[1, 2, 3]
>>> bar.append(4)
>>> foo, bar
([1, 2, 3, 4], [1, 2, 3, 4])
>>> id(foo), id(bar)
(4477098392, 4477098392)

Both foo and bar参考同一个列表,该列表未被复制。要创建副本,请使用list()构造函数或使用[:]切片运算符:

>>> bar = foo[:]
>>> bar.append(5)
>>> foo, bar
([1, 2, 3, 4], [1, 2, 3, 4, 5])
>>> id(foo), id(bar)
(4477098392, 4477098536)

Now bar是列表的新副本,并且更改不再可见foo。内存地址(结果id()调用)对于两个列表来说是不同的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

合并字典而不覆盖值 的相关文章

随机推荐