python使用{}.fromkeys创建字典后,通过append更新list型value出错?
问题描述:
方式1:
list= {‘1’, ‘2’, ‘3’, ‘4’}
然后根据该序列初始化字典dic1,并设置其值默认格式为list:
dic1={}.fromkeys(list,[])
print dic1
输出:{‘1’: [], ‘2’: [], ‘3’: [], ‘4’: []}
一切都是对的:
然后为key为’a’的键更新value:
dic1[‘1’].append(1)
print dic1
可输出竟然是:
{‘1’: [1], ‘2’: [1], ‘3’: [1], ‘4’: [1]}
按道理应该是
{‘1’: [1], ‘2’: [], ‘3’: [], ‘4’: []}
方式2:
如果我们换一种方式创建:
dic1={‘1’: [], ‘2’: [], ‘3’: [], ‘4’: []}
print dic1
输出:{‘1’: [], ‘2’: [], ‘3’: [], ‘4’: []}
然后为key为’a’的键更新value:
dic1[‘1’].append(1)
print dic1
输出:{‘1’: [1], ‘2’: [], ‘3’: [], ‘4’: []} 此时就是我想要的。
经过分析得出以下总结:
原因是第一种方式的列表都是一个对象(始终是用同一个[]进行初始化,导致他们的key的变量地址都是相同),第二种方式则都是不同的对象(他们的key的变量地址是不同的)。
In [1]: header= {'a', 'c', 'b', 'e', 'f'}
In [2]: dic1={}.fromkeys(header,[])
In [3]: dic1
Out[3]: {'a': [], 'b': [], 'c': [], 'e': [], 'f': []}
In [4]: dic1['a'] is dic1['b']
Out[4]: True
In [5]: dic2={'a': [], 'c': [], 'b': [], 'e': [], 'f': []}
In [6]: dic2['a'] is dic2['b']
Out[6]: False
引申说明:
Python 中 list 是可变类型,在作为参数传递的时候是传引用的。所以 fromkeys 函数把所有 key 都指向了同一个空列表。改动其中任何一个,其他的都改掉了。因此就会出现方式1出现的问题。
我们可以通过以下方式来改进
#list为关键字的列表
#dic1={}.fromkeys(list,[])
dic1 = {k:[] for k in list}