字典将值赋予特定键,而其他键则赋予相同值

时间:2020-01-18 09:27:07

标签: python dictionary

我想创建一个字典来记录程序运行时的准确性。当我将值赋给某个​​键时出现一些问题

在这里,我创建了一个字典来记录训练或验证时的准确性

acc = dict.fromkeys(['train', 'val'], dict.fromkeys(['pa', 'iou', 'dice'], 0))

原始字典是这样

{'train': {'pa': 0, 'iou': 0, 'dice': 0}, 'val': {'pa': 0, 'iou': 0, 'dice': 0}}

现在,我给出一些测试值

acc['train']['pa'] = 0.9
acc['train']['iou'] = 0.8
acc['train']['dice'] = 0.7

问题在于密钥val中的所有值都相同

{'train': {'pa': 0.9, 'iou': 0.8, 'dice': 0.7}, 'val': {'pa': 0.9, 'iou': 0.8, 'dice': 0.7}}

2 个答案:

答案 0 :(得分:1)

如果提供的值是可变对象(可以更改其值),如列表,字典等,则当修改可变对象时,序列中的每个元素也会更新。 这是因为,每个元素都分配了对同一对象的引用(指向内存中的同一对象)。

在您遇到的问题中,dict.fromkeys(['pa', 'iou', 'dice'], 0)返回的是可变类型的字典,因此每个元素都分配给相同的对象。

为避免此问题,可以使用字典理解。

from copy import copy
# keys
keys = ['train', 'val']
value = dict.fromkeys(['pa', 'iou', 'dice'], 0 )

acc = { key : copy(value) for key in keys }

print(acc)

# updating the value
acc['train']['pa'] = 2 
print(acc)

来源:https://www.programiz.com/python-programming/methods/dictionary/fromkeys

答案 1 :(得分:1)

这是因为dict.fromkeys(['pa', 'iou', 'dice'], 0)仅被调用一次,而不是acc中的每个键都被调用一次。

>>> acc['train'] is acc['val']                                                  
True

字典是内存中的同一对象,您只有两种访问方式-通过acc['train']acc['val']来访问。

您可以将defaultdict与可按需创建新字典的函数一起使用:

>>> from collections import defaultdict                                         
>>> d = defaultdict(lambda: {'pa': 0, 'iou': 0, 'dice': 0})                     
>>> d['train']                                                                  
{'pa': 0, 'iou': 0, 'dice': 0}
>>> d['val']                                                                    
{'pa': 0, 'iou': 0, 'dice': 0}
>>> d['train']['pa'] = 1                                                        
>>> d['train']                                                                  
{'pa': 1, 'iou': 0, 'dice': 0}
>>> d['val']                                                                    
{'pa': 0, 'iou': 0, 'dice': 0}

但是,请注意,每次您访问新密钥时,都会创建一个新字典:

>>> d['foo']                                                                    
{'pa': 0, 'iou': 0, 'dice': 0}

如果您不想这么做,请使用dict理解为每个键手动创建一个字典:

>>> keys = ['train', 'val']                                                     
>>> d = {k:{'pa': 0, 'iou': 0, 'dice': 0} for k in keys}
>>> d['train']['pa'] = 1                                                        
>>> d['train']                                                                  
{'pa': 1, 'iou': 0, 'dice': 0}
>>> d['val']                                                                    
{'pa': 0, 'iou': 0, 'dice': 0}
相关问题