为dict.fromkeys()和花括号初始化的dict赋值时,为什么会有区别?

时间:2017-03-26 10:20:17

标签: python python-2.7 dictionary

这是一个例子,

my_keys=['hi','hello']
d=dict.fromkeys(my_keys,[])
print d
d['hello'].append([1,])
print d['hello']
print d['hi']

d={'hi': [], 'hello': []}
print d
d['hello'].append([1,])
print d['hello']
print d['hi']

输出:

{'hi': [], 'hello': []}
[[1]]
[[1]]
{'hi': [], 'hello': []}
[[1]]
[]

通过输出,可以看出,当修改了一个键的值时,如果使用d['hello'].append([1,])

初始化dict,那么dict.fromkeys()会更改键'hi'的值。
  

classmethod fromkeys(seq[, value])
  使用 seq 中的键创建一个新词典,并将值设置为 value

为使用dict.fromkeys()和花括号初始化的字典赋值时,为什么会有区别?

1 个答案:

答案 0 :(得分:1)

dict.fromkeys()不会复制您传入的值,因此您只有一个列表对象。您的{...}字词文字会创建两个单独的列表

请记住,在Python名称中,容器(如列表或字典)中包含的属性和对象只是引用到堆上的对象。您可以轻松地创建对同一对象的多个引用。 dict.fromkeys()只需获取您传入的引用,然后将其重用于所有值。因此d中的所有值都指向同一个列表对象:

>>> my_keys = ['hi', 'hello']
>>> d = dict.fromkeys(my_keys)
>>> d['hi'] is d['hello']
True
>>> id(d['hi']), id(d['hello'])
(4508307448, 4508307448)

使用dict理解从键列表创建字典,您需要为这些键生成单独的对象:

{k: [] for k in my_keys}

在dict理解中,为for循环的每次迭代计算值表达式,因此[]表达式一次又一次地执行以生成单独的列表对象:

>>> d = {k: [] for k in my_keys}
>>> d['hi'] is d['hello']
False
>>> id(d['hi']), id(d['hello'])
(4514233544, 4514233672)