Python:为什么listA.append('a')影响listB? [英] python: Why listA.append('a') affects listB?
问题描述
这是我的代码:
In [8]: b=dict.fromkeys([1,2,3,4], [])
In [9]: b[1].append(1)
In [10]: b[2].append(2)
In [11]: b[1]
Out[11]: [1, 2]
In [12]: b[2]
Out[12]: [1, 2]
In [13]: b
Out[13]: {1: [1, 2], 2: [1, 2], 3: [1, 2], 4: [1, 2]}
我希望:{1:[1],2:[2],3:[],4:[]}
Whereas I would expect: {1: [1], 2: [2], 3: [], 4: []}
我想这可能是b [X]只是一个引用"所致,它们都引用相同的列表.
I guess this is maybe caused by b[X] is just a "reference", they all refer to a same list.
然后我将[]替换为一个int对象.结果让我更加困惑:
Then I replace [] with an int object. The result makes me more confused:
In [15]: b=dict.fromkeys([1,2,3,4], 1)
In [16]: b[1] += 1
In [17]: b[2] += 1
In [18]: b
Out[18]: {1: 2, 2: 2, 3: 1, 4: 1}
在这种情况下,此int对象1不是引用.
This int object 1 isn't a referance in this case.
然后我将[]替换为['a']:
Then I replace [] with ['a']:
In [19]: b=dict.fromkeys([1,2,3,4], ['a'])
In [20]: b[1].append(1)
In [21]: b[2].append(2)
In [22]: b
Out[22]: {1: ['a', 1, 2], 2: ['a', 1, 2], 3: ['a', 1, 2], 4: ['a', 1, 2]}
现在['a']再次成为参考.
Now ['a'] is a reference again.
在第一种情况下,有人可以告诉我原因以及如何获得预期的结果"{1:[1],2:[2],3:[],4:[]}".
Can someone tells me why, and how to get expected result "{1: [1], 2: [2], 3: [], 4: []}" in the first case.
任何有用的建议都会受到赞赏.
Any useful suggestions are appreciated.
推荐答案
由于dict中的所有值实际上都是对同一列表的引用,因此dict.fromkeys
使用相同的列表对象并将其分配给每个键.由于list.append
是就地操作,因此所有键都会受到影响.
Because all values in the dict are actually references to the same list, dict.fromkeys
uses the same list object and assigns it to each key. As list.append
is an in-place operation so all keys are affected.
>>> b = dict.fromkeys([1,2,3,4], [])
>>> [id(x) for x in b.values()]
[158948300, 158948300, 158948300, 158948300]
因此,对于可变值,请使用dict理解:
So, for mutable value use a dict comprehension:
>>> b = {k:[] for k in xrange(1, 5)}
>>> [id(x) for x in b.values()]
[158945580, 158948396, 158948108, 158946764]
或者按照@Bakuriu的建议,collections.defaultdict
也可以正常工作:
Or as @Bakuriu suggested, collections.defaultdict
will also work fine:
>>> from collections import defaultdict
>>> dic = defaultdict(list)
>>> dic[1].append(1)
>>> dic[2].append(2)
>>> dic
defaultdict(<type 'list'>, {1: [1], 2: [2]})
>>> dic[3]
[]
这篇关于Python:为什么listA.append('a')影响listB?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!