我声明了一个Python字典,其中的键和值是多个数组。是否可以使用键和值索引附加数组?
这是我初始化python字典cvfoldacc的方式
a = []
b = []
c = []
d = []
e = []
f = []
classifiers = [a,b,c,d,e,f]
cvfoldacc = dict.fromkeys(range(2,11), classifiers)
此初始化的结果如下:
cvfoldacc>>
{2: [[], [], [], [], [], []],
3: [[], [], [], [], [], []],
4: [[], [], [], [], [], []],
5: [[], [], [], [], [], []],
6: [[], [], [], [], [], []],
7: [[], [], [], [], [], []],
8: [[], [], [], [], [], []],
9: [[], [], [], [], [], []],
10: [[], [], [], [], [], []]}
当我尝试将key(2)的第一个列表附加到代码中时 cvfoldacc [2] [0] .append(8),我得到的结果是:
{2: [[8], [], [], [], [], []],
3: [[8], [], [], [], [], []],
4: [[8], [], [], [], [], []],
5: [[8], [], [], [], [], []],
6: [[8], [], [], [], [], []],
7: [[8], [], [], [], [], []],
8: [[8], [], [], [], [], []],
9: [[8], [], [], [], [], []],
10: [[8], [], [], [], [], []]}
但是预期的答案应该是这样:
{2: [[8], [], [], [], [], []],
3: [[], [], [], [], [], []],
4: [[], [], [], [], [], []],
5: [[], [], [], [], [], []],
6: [[], [], [], [], [], []],
7: [[], [], [], [], [], []],
8: [[], [], [], [], [], []],
9: [[], [], [], [], [], []],
10: [[], [], [], [], [], []]}
答案 0 :(得分:2)
这是旧的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()
创建了外部列表的副本,内部列表也是相同的。因此,基本上,您要追加list: a
中存在的keys
,以便对所有内容进行修改。
Deepcopy
递归复制所有对象,从而避免了该问题。
答案 1 :(得分:1)
您需要为每个list
之类的值创建新的key
,
>>> a = []
>>> b = []
>>> c = []
>>> d = []
>>> e = []
>>> f = []
>>> classifiers = [a,b,c,d,e,f]
>>>
>>> d = {k:[x[:] for x in classifiers] for k in range(2,11)} # note i am creating a copy using the `list[:]` notation.
# either the comprehension or `k: copy.deepcopy(classifiers)` is fine
>>> d
{2: [[], [], [], [], [], []], 3: [[], [], [], [], [], []], 4: [[], [], [], [], [], []], 5: [[], [], [], [], [], []], 6: [[], [], [], [], [], []], 7: [[], [], [], [], [], []], 8: [[], [], [], [], [], []], 9: [[], [], [], [], [], []], 10: [[], [], [], [], [], []]}
>>> d[2][0].append(1)
>>> d
{2: [[1], [], [], [], [], []], 3: [[], [], [], [], [], []], 4: [[], [], [], [], [], []], 5: [[], [], [], [], [], []], 6: [[], [], [], [], [], []], 7: [[], [], [], [], [], []], 8: [[], [], [], [], [], []], 9: [[], [], [], [], [], []], 10: [[], [], [], [], [], []]}