为什么在相同但创建不同的嵌套字典中将值分配给键会导致不同的结果?

Why does the assignment of values to keys in identical, but differently created nested dictionaries leads to different results?

代码片段值一千字,所以它们是:

# Creation of data_dict1
data_types = ('abnormal', 'normal')
data_dict1 = dict.fromkeys(data_types, {0: {}, 1: {}})
# Creation of data_dict2
data_dict2 = data_dict2 = {'abnormal': {0: {}, 1: {}}, 'normal': {0: {}, 1: {}}}

# Check
print(data_dict1)
print(data_dict2)
print(data_dict1 == data_dict2)

>>> {'abnormal': {0: {}, 1: {}}, 'normal': {0: {}, 1: {}}}
>>> {'abnormal': {0: {}, 1: {}}, 'normal': {0: {}, 1: {}}}
>>> True

如您所见,嵌套字典 data_dict1data_dict2 是相同的,无论其方法如何的创作。 但是当我以同样的方式赋值时,我得到了不同的结果:

data_dict1['abnormal'][0]['result'] = 'abnormal_0'
data_dict1['abnormal'][1]['result'] = 'abnormal_1'
data_dict1['normal'][0]['result'] = 'normal_0'
data_dict1['normal'][1]['result'] = 'normal_1'

data_dict2['abnormal'][0]['result'] = 'abnormal_0'
data_dict2['abnormal'][1]['result'] = 'abnormal_1'
data_dict2['normal'][0]['result'] = 'normal_0'
data_dict2['normal'][1]['result'] = 'normal_1'

# Check
print(data_dict1)
print(data_dict2)
print(data_dict1 == data_dict2)

>>> {'abnormal': {0: {'result': 'normal_0'}, 1: {'result': 'normal_1'}}, 'normal': {0: {'result': 'normal_0'}, 1: {'result': 'normal_1'}}}
>>> {'abnormal': {0: {'result': 'abnormal_0'}, 1: {'result': 'abnormal_1'}}, 'normal': {0: {'result': 'normal_0'}, 1: {'result': 'normal_1'}}}
>>> False

data_dict1['abnormal'][0]['result'][=42= 的值]['abnormal'][0]['result']'normal_0''normal_1' ,而不是 'abnormal_0''abnormal_1'。为什么会这样?

这要归功于您启动的方式 data_dict1

data_dict1 = dict.fromkeys(data_types, {0: {}, 1: {}})

执行此操作时,data_dict1 中的两个键都设置为同一个嵌套字典。这意味着在这些行之后:

data_dict1['abnormal'][0]['result'] = 'abnormal_0'
data_dict1['abnormal'][1]['result'] = 'abnormal_1'

字典中的两个键 abnormalnormal 的值都已更改。如果我们此时检查 data_dict1,我们会看到:

>>> data_dict1
{'abnormal': {0: {'result': 'abnormal_0'}, 1: {'result': 'abnormal_1'}},
 'normal': {0: {'result': 'abnormal_0'}, 1: {'result': 'abnormal_1'}}}

当我们继续更改 normal 键的值时,同样的事情发生了,给我们您找到的结果。

我们可以使用 is:

检查两个嵌套字典实际上是内存中的同一个字典
>>> data_dict1['abnormal'] is data_dict1['normal']
True

你已经通过实际为键分配不同的嵌套字典来启动data_dict2,我们可以看到这与上面的方式相同:

>>> data_dict2['abnormal'] is data_dict2['normal']
False

我们可以避免这种行为,而不必像在 data_dict2 中那样输入它。一种方法是使用字典理解:

>>> data_types = ('abnormal', 'normal')
>>> data_dict1 = {k: {0: {}, 1: {}} for k in data_types}
>>> data_dict1['abnormal'] is data_dict1['normal']
False