使用tf.keras.optimizers.get更新字典b时为何会意外修改原字典a的值?
成因
- 你创建字典
b时使用的字典推导式属于浅拷贝,只会复制父字典的结构,字典内嵌套的可变对象(比如a['y']对应的子字典)不会被复制,而是直接引用原对象,你验证的a['y'] is b['y']返回True就证明了二者指向同一个内存地址的对象。 tf.keras.optimizers.get的内部实现会直接修改传入的配置字典:为了统一匹配优化器名称,该函数会主动将传入字典的class_name字段转为小写,且这个修改是直接在传入的原字典上执行的,没有预先复制独立副本。
你将b['y']传入该函数时,实际修改的就是和a['y']共用的那个子字典对象,哪怕后续你把b['y']重新赋值为优化器实例,之前的子字典修改已经生效,所以a['y']['class_name']会变成小写。
而你修改b['x']时不会影响a,是因为x对应的值是整数这种不可变类型,修改时会生成新的整数对象并重新赋值给b['x'],不会改动原有的值。
规避方法
- 方案1:创建
b时使用深拷贝,完全隔离两个字典的嵌套对象
import copy b = copy.deepcopy(a)
- 方案2:给
tf.keras.optimizers.get传参时,先传入配置字典的副本
b['y'] = tf.keras.optimizers.get(b['y'].copy())
内容的提问来源于stack exchange,提问作者akilat90
相关产品推荐
相关产品推荐

