vijayvammi
vijayvammi

Reputation: 376

Python dictionary initialization?

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

Answers (2)

MikeyB
MikeyB

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

NPE
NPE

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

Related Questions