简体   繁体   中英

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.

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)

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) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM