Python:如何避免字典按引用传递?不重建对象实现拷贝
搞定Python字典append到列表的引用坑!
嘿,这个问题我之前也踩过!本质就是Python里可变对象的引用特性搞的鬼——字典是可变类型,你每次append(my_dict)的时候,压根没把字典本身放进列表,放的是指向这个字典的引用。所以循环跑完,列表里三个元素全指向同一个字典,自然都是最后一次修改的{'id': '2'}了。
最Pythonic的解法:用字典的copy()方法
完全不用在循环里重新声明新字典,每次改完原字典,把它的浅拷贝丢进列表就行:
my_dict = {} my_list = [] for i in range(3): my_dict['id'] = str(i) my_list.append(my_dict.copy()) # 关键:加个copy(),存拷贝而非原引用
跑出来my_list就是你想要的:[{'id': '0'}, {'id': '1'}, {'id': '2'}]
另一种等价写法:用dict()构造拷贝
和copy()效果一模一样,只是写法上换了种方式,用dict()包装原字典生成新拷贝:
my_dict = {} my_list = [] for i in range(3): my_dict['id'] = str(i) my_list.append(dict(my_dict))
关于“不重建对象又不传递引用”的说明
这里得掰扯清楚:如果你不想让列表元素指向同一个字典,必须生成新的字典实例——也就是拷贝。所谓“不重建对象”应该是指不用每次循环都my_dict = {}重新声明变量对吧?那上面的方法完全满足:原字典变量一直是同一个,我们只是把它当前状态的拷贝放进列表,既没重新声明变量,又避免了引用问题。
要是追求极致简洁,其实也可以用列表推导式直接生成每个字典,但那相当于在循环里新建字典了,不符合你“无需在循环内重新声明字典”的要求,所以还是拷贝的方法最贴合你的需求。
内容的提问来源于stack exchange,提问作者Dadou
相关产品推荐
相关产品推荐

