为什么使用fromkeys初始化列表字典会影响列表的附加方式

时间:2017-09-16 07:15:34

标签: python list dictionary

使用不同的方法创建列表的字典

d1 = {'foo':[],'bar':[]}
d2 = dict.fromkeys(['foo','bar'],[])

产生两个相同的词组。

print(d1==d2,d1,d2)

True {'foo': [], 'bar': []} {'foo': [], 'bar': []}

但是,将值附加到列表

d1['foo'].append('a')
d2['foo'].append('a')

d1['foo'].append(2)
d2['foo'].append(2)

产生两种不同的词汇。为什么dict的初始化方法会影响列表追加行为?

print(d1==d2,d1,d2)

False {'foo': ['a', 2], 'bar': []} {'foo': ['a', 2], 'bar': ['a', 2]}

在fromkeys之后,python也将list append语句应用于所有其他键。

1 个答案:

答案 0 :(得分:3)

当你使用fromkeys时,正在发生的是正在创建字典,并且它的所有键都与它们的值具有相同的对象。

这意味着d2["foo"]d2["bar"]都指向同一个对象。它是相同的对象,而不仅仅是相同的对象。因此,通过一个键修改它会将其更改为所有其他键。

如果您使用自定义对象,则会更加明显:

class MyClass:
    def __init__(self):
        pass

a = MyClass()
d = dict.fromkeys(["foo", "bar"], a)

打印d会产生以下输出:

{'foo': <__main__.MyClass object at 0x0000000004699AC8>, 'bar': <__main__.MyClass object at 0x0000000004699AC8>}

注意内存地址是如何相同的,因为它是同一个对象。

但是,在d1中,您不会为两个键分配相同的对象。而是分配两个单独的相同的(空列表)。因此,修改一个不会改变另一个。