Py学习  »  Python

如果值是多数组,则使用键将值附加到python字典值

user2159982 • 6 年前 • 1992 次点击  

我声明了一个python字典,其中键和值都是多数组。是否可以使用键和值索引追加数组?

这是我初始化python字典cvfoldac的方式

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: [[], [], [], [], [], []]}

当我试图用代码附加键(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: [[], [], [], [], [], []]}
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/49518
文章 [ 2 ]  |  最新文章 6 年前
Sayandip Dutta
Reply   •   1 楼
Sayandip Dutta    6 年前

这是同一个旧的 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 递归地复制了所有对象,避免了这个问题。

han solo
Reply   •   2 楼
han solo    6 年前

你需要创建新的 list s表示每个 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: [[], [], [], [], [], []]}