【解决循环创建字典时的覆盖问题】浅拷贝copy & 深拷贝deepcopy

遇到问题:循环创建字典,传入列表会引起覆盖问题

构造数据集时,每个数据存储为字典的结构,类似于:

{
	"123(data_id)": {
		"detail":{....},
		"QA":{.....}
	}
}

每条数据都有一个data_id,并且包含一些细节信息detail、问答对QA。将每条数据构建好后插入list存储为json后发现,字典中的一些信息发生错误,最后一条数据的字典中部分信息覆盖了前面所有数据的该部分信息。
debug后发现错因:

引用问题:
如果在向列表中添加字典时,实际上是添加了字典对象的引用而不是副本,那么后续对字典对象的修改会影响到之前添加的内容。

举个简单例子,例如:

l = []
d1 = {
    "a":1
}
l.append(d1)
d1['a'] = 10
print(l) 
"""
[{"a": 10}]
"""

解决方法:
使用深拷贝(deepcopy)来创建字典的副本,或者确保在每次循环迭代时都创建一个全新的字典对象,并将其添加到列表中,以确保它们是独立的。

例如:

l = []
d1 = {
    "a":1
}
l.append(d1)
d1['a'] = 10

d2 = {
    "b": 2
}
l.append(copy.deepcopy(d2))
d2['b'] = 20
print(l)
"""
[{"a": 10}, {"b": 2}]
"""

浅拷贝copy & 深拷贝deepcopy

  1. copy:copy函数是copy模块中的函数,用于创建一个浅拷贝(shallow copy)的对象。浅拷贝创建了一个新对象,该对象与原始对象共享内部对象的引用。这意味着对于可变对象,修改副本可能会影响原始对象。但对于不可变对象,修改副本不会影响原始对象。

  2. deepcopy:deepcopy函数也是copy模块中的函数,用于创建一个深拷贝(deep copy)的对象。深拷贝创建了一个全新的对象,包括所有内部对象的副本,而不是仅仅共享引用。这意味着无论是可变对象还是不可变对象,修改副本都不会影响原始对象。

例如:

import copy

# 创建一个列表
original_list = [1, 2, [3, 4]]

# 浅拷贝
shallow_copy = copy.copy(original_list)
shallow_copy[2].append(5)

print(original_list)  # 输出: [1, 2, [3, 4, 5]]
print(shallow_copy)   # 输出: [1, 2, [3, 4, 5]]

# 深拷贝
deep_copy = copy.deepcopy(original_list)
deep_copy[2].append(6)

print(original_list)  # 输出: [1, 2, [3, 4, 5]]
print(deep_copy)      # 输出: [1, 2, [3, 4, 5, 6]]

总结

在深度学习构建数据集时,经常需要将每条数据存储为字典,依次传入列表,存储为json。注意往列表中传字典时,最好使用deepcopy后的字典传入

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值