这是同一个旧的
deep copy
对
shallow copy
事情。
试试这个:
>>> a = []
>>> b = []
>>> c = []
>>> d = []
>>> e = []
>>> f = []
>>> classifiers = [a,b,c,d,e,f]
>>> import copy
>>> cvfoldacc = {k:copy.deepcopy(classifiers) for k in range(2,11)}
>>> cvfoldacc[2][0].append(8)
>>> cvfoldacc
{2: [[8], [], [], [], [], []],
3: [[], [], [], [], [], []],
4: [[], [], [], [], [], []],
5: [[], [], [], [], [], []],
6: [[], [], [], [], [], []],
7: [[], [], [], [], [], []],
8: [[], [], [], [], [], []],
9: [[], [], [], [], [], []],
10: [[], [], [], [], [], []]}
你在做:
a = []
b = []
c = []
d = []
e = []
f = []
classifiers = [a,b,c,d,e,f]
cvfoldacc = dict.fromkeys(range(2,11), classifiers)
现在,正在创建的字典在每个键中都有相同的列表,不仅它们看起来相同,而且它们是完全相同的对象,具有相同的
identity
(CPython中的内存位置)。让我们看看:
>>> id(cvfoldacc[2])
171760008
>>> id(cvfoldacc[3])
171760008
其他价值观也一样。
所以
dict.fromkeys()
为字典中的所有键指定相同的值,而不创建其副本。
现在,另一种方法,你做一个浅显的复制,这个问题就解决了:
>>> cvfoldacc = {a:classifiers.copy() for a in range(2,11)}
>>> id(cvfoldacc[2])
171840616
>>> id(cvfoldacc[3])
171847688
解决了对吧?
>>> cvfoldacc[2][0].append(8)
{2: [[8], [], [], [], [], []],
3: [[8], [], [], [], [], []],
4: [[8], [], [], [], [], []],
5: [[8], [], [], [], [], []],
6: [[8], [], [], [], [], []],
7: [[8], [], [], [], [], []],
8: [[8], [], [], [], [], []],
9: [[8], [], [], [], [], []],
10: [[8], [], [], [], [], []]}
显然不是!!让我们现在看得更深一点。让我们看看
id
列表中的列表:
>>> id(cvfoldacc[2][0])
171810120
>>> id(cvfoldacc[3][0])
171810120
尽管如此
list.copy()
创建了outerlist的副本,内部列表是相同的。所以本质上你是在
list: a
它存在于
keys
所以一切都在改变。
Deepcopy
递归地复制了所有对象,避免了这个问题。