如何为嵌套字典特定键组合赋值?为何所有子字典同步变更?
嵌套字典赋值同步问题:原因与解决方案
问题原因
这不是预期行为,核心问题在于Python中可变对象的引用传递特性。字典是可变对象,你在循环中执行consolidated_results[input_type] = results时,并没有为每个input_type创建独立的字典实例,而是让所有input_type对应的value都指向同一个results字典对象。因此,修改任意一个input_type下的键值,本质都是在修改同一个底层字典,导致所有条目同步变化。
正确操作方法
方法1:使用浅拷贝(适用于顶层键值独立修改的场景)
通过dict.copy()为每个input_type创建results的浅拷贝,确保每个条目对应独立的字典:
results = { 'mape_train_dummy':[], 'rmse_train_dummy':[], 'mape_test_dummy':[], 'rmse_test_dummy':[], 'mape_train_pinn':[], 'rmse_train_pinn':[], 'mape_test_pinn':[], 'rmse_test_pinn':[], 'y_train_true':[], 'y_train_pred':[], 'y_test_true':[], 'y_test_pred':[], 'best_model':[], 'mape_test_dummy_socs':[], 'rmse_test_dummy_socs':[], 'mape_test_pinn_socs':[], 'rmse_test_pinn_socs':[] } consolidated_results = {} input_types = ['type1', 'type2', 'type3', 'type4', 'type5'] for input_type in input_types: consolidated_results[input_type] = results.copy() input_type = input_types[0] consolidated_results[input_type]['mape_train_dummy'] = 50
此时修改type1的键值不会影响其他input_type的条目。
方法2:使用深拷贝(适用于需要修改嵌套可变对象的场景)
如果后续需要修改字典内的列表元素(比如向列表追加内容),浅拷贝会因为列表也是可变对象导致引用共享,这时需要用copy.deepcopy()创建完全独立的副本:
import copy results = { # 同原字典内容 } consolidated_results = {} input_types = ['type1', 'type2', 'type3', 'type4', 'type5'] for input_type in input_types: consolidated_results[input_type] = copy.deepcopy(results) input_type = input_types[0] consolidated_results[input_type]['mape_train_dummy'] = 50
方法3:循环内直接创建新字典
直接在循环中为每个input_type定义全新的字典,从根源避免引用共享:
consolidated_results = {} input_types = ['type1', 'type2', 'type3', 'type4', 'type5'] for input_type in input_types: consolidated_results[input_type] = { 'mape_train_dummy':[], 'rmse_train_dummy':[], 'mape_test_dummy':[], 'rmse_test_dummy':[], 'mape_train_pinn':[], 'rmse_train_pinn':[], 'mape_test_pinn':[], 'rmse_test_pinn':[], 'y_train_true':[], 'y_train_pred':[], 'y_test_true':[], 'y_test_pred':[], 'best_model':[], 'mape_test_dummy_socs':[], 'rmse_test_dummy_socs':[], 'mape_test_pinn_socs':[], 'rmse_test_pinn_socs':[] } input_type = input_types[0] consolidated_results[input_type]['mape_train_dummy'] = 50
效果验证
执行上述修改后的代码后,你会得到预期结果:
print(consolidated_results['type1']['mape_train_dummy']) # 输出 50 print(consolidated_results['type2']['mape_train_dummy']) # 输出 []
内容的提问来源于stack exchange,提问作者tom sawyer
相关产品推荐
相关产品推荐

