我想创建一个字典来记录程序运行时的准确性。当我将值赋给某个键时出现一些问题
在这里,我创建了一个字典来记录训练或验证时的准确性
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}}
答案 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}