看起来很简单:
我正在尝试合并2个字典而不覆盖值,但要追加。
a = {1: [(1,1)],2: [(2,2),(3,3)],3: [(4,4)]}
b = {3: [(5,5)], 4: [(6,6)]}
Run Code Online (Sandbox Code Playgroud)
元组数a = 4,元组数b = 2
这就是为什么我会选择这些选项,因为它们被覆盖了:
all = dict(a.items() + b.items())
all = dict(a, **b)
all = a.update([b])
Run Code Online (Sandbox Code Playgroud)
以下解决方案可以正常工作,但也可以将值附加到我的原始字典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]
Run Code Online (Sandbox Code Playgroud)
输出=
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)]}
Run Code Online (Sandbox Code Playgroud)
元组的数量= 5 !!!!! ,元组数b = 2(正确),元组全部= 6(正确)
它将元组[(5,5)]从b 追加到a。我不知道为什么会这样,因为我正在编码的只是将所有内容都写到完整的字典“ all”中。
谁能告诉我它在哪里改变dict(a)???????
任何帮助都非常欢迎。
用于.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]
Run Code Online (Sandbox Code Playgroud)
此外,您可以使用来遍历两者的键和值,a以及b一起使用itertools.chain:
from itertools import chain
all = {}
for k, v in chain(a.iteritems(), b.iteritems()):
all.setdefault(k, []).extend(v)
Run Code Online (Sandbox Code Playgroud)
.setdefault()查找一个密钥,并将其设置为默认值(如果尚未存在)。另外,您可以使用collections.defaultdict隐式执行相同操作。
输出:
>>> 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)]}
Run Code Online (Sandbox Code Playgroud)
请注意,由于我们现在首先为每个键创建一个干净的新列表,然后进行扩展,因此原始列表a不会受到影响。在您的代码中,您不会创建列表的副本。而是将引用复制到列表中。最后,all和adict值都指向相同的列表,在这些列表上使用append会使更改在两个地方都可见。
用简单的变量而不是字典可以很容易地证明这一点:
>>> 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)
Run Code Online (Sandbox Code Playgroud)
两者foo并bar引用同一列表,但列表未复制。要创建副本,请使用list()构造函数或使用[:]slice运算符:
>>> bar = foo[:]
>>> bar.append(5)
>>> foo, bar
([1, 2, 3, 4], [1, 2, 3, 4, 5])
>>> id(foo), id(bar)
(4477098392, 4477098536)
Run Code Online (Sandbox Code Playgroud)
现在bar是该列表的新副本,并且中的更改不再可见foo。id()两个列表的内存地址(调用的结果)不同。