Reputation: 376
I am not sure if this is a bug or a feature. I have a dictionary to be initialized with empty lists.
Lets say
keys =['one','two','three']
sets = dict.fromkeys(keys,[])
What I observed is if you append any item to any of the lists all the lists are modified.
sets = dict.fromkeys(['one','two','three'],[])
sets['one'].append(1)
sets
{'three': [1],'two': [1], 'one': [1]}
But when I do it manually using loop,
for key in keys:
sets[key] = []
sets['one'].append(1)
sets
{'three': [], 'two': [], 'one': [1]}
I would think the second behavior should be the default.
Upvotes: 4
Views: 458
Reputation: 3350
Other answers covered the 'Why', so here's the how.
You should use a comprehension to create your desired dictionary:
>>> keys = ['one','two','three']
>>> sets = { x: [] for x in keys }
>>> sets['one'].append(1)
>>> sets
{'three': [], 'two': [], 'one': [1]}
For Python 2.6 and below, the dictionary comprehension can be replaced with:
>>> sets = dict( ((x,[]) for x in keys) )
Upvotes: 5
Reputation: 500187
This is how things work in Python.
When you use fromkeys()
in this manner, you end with three references to the same list. When you change one list, all three appear to change.
The same behaviour can also be seen here:
In [2]: l = [[]] * 3
In [3]: l
Out[3]: [[], [], []]
In [4]: l[0].append('one')
In [5]: l
Out[5]: [['one'], ['one'], ['one']]
Again, the three lists are in fact three references to the same list:
In [6]: map(id, l)
Out[6]: [18459824, 18459824, 18459824]
(notice how they have the same id)
Upvotes: 10