Skip to content Skip to sidebar Skip to footer

Python: Why Lista.append('a') Affects Listb?

This is my code: 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 O

Solution 1:

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]

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]

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]
[]

Solution 2:

They really are all references. The difference is what you do with the references.

When you use the assignment operator =, you're setting the reference to a different object. (+= works the same).

When you use append, you're modifying the object without affecting the reference. Since fromkeys gave back multiple references to the same object, the modifications are seen in all of them simultaneously.

Post a Comment for "Python: Why Lista.append('a') Affects Listb?"