[Python]list.append字典的时候,修改字典会导致list内容变化的问题

时间:2021-10-16 00:05:31

今天写了这样的一段代码,出现了BUG。

log_message["EventName"] = "上架->可用"
log_message["EventNum"] = all_diff
event_log.append(log_message)

log_message["EventName"] = "可用->停用"
log_message["EventNum"] = stop_diff
event_log.append(log_message)

 BUG表现为,第二条log_message在event_log中出现了两次,第一条message则不见了。

网上可以找到一样的问题:[Python]list.append()在for循环中每次添加的都是最后的一个元素

主要原因是dict是一个可变的对象,list在append的时候,只是append了对象的引用,没有append对象的数据。修改了对象之后,之前append过的对象也会发生变化。

之前虽然知道dict可变,但以为是append之后,list会将数据固定下来,不再让其可变。事实证明list append的只是对象的引用。这样的思路其实也对,因为这样设计会节省内存。

 

要解决这个问题, 一是向list中插入不可变对象,如将dict变为tuple类型。

另外就是每次都插入一个新的对象,而不是对象的引用。如 event_log.append(log_message1),  event_log.append(log_message2).

完全重新声明一个log_message2对我来说有点麻烦,log_message的其他字段初始化有点繁琐。

所以我选择复制一个。复制的话依然需要小心引用的问题,有关拷贝对象可以参考这个:Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)

import copy

log_message["EventName"] = "上架->可用"
log_message["EventNum"] = all_diff
event_log.append(log_message)

log_message2 = copy.deepcopy(log_message)
log_message2["EventName"] = "可用->停用"
log_message2["EventNum"] = stop_diff
event_log.append(log_message2)