先看下面问题例子:
def wrong_sample():
a = {'x': 1, 'y': 2, 'z': 3}
b = []
b.append(a)
print("1a", a)
print("1b", b)
a["x"] = 5
print("2a", a)
print("2b", b)
b.append(a)
print("3a", a)
print("3b", b)
运行结果:''
1a {'x': 1, 'y': 2, 'z': 3}
1b [{'x': 1, 'y': 2, 'z': 3}]
2a {'x': 5, 'y': 2, 'z': 3} a[x]改变了
2b [{'x': 5, 'y': 2, 'z': 3}] 我们看到同时在列表中的字典的a[x]也被改变了,
3a {'x': 5, 'y': 2, 'z': 3}
3b [{'x': 5, 'y': 2, 'z': 3}, {'x': 5, 'y': 2, 'z': 3}
解决方法1:使用 copy模块下的deepcopy,但这个有问题,如果循环超过999次使用,则会报 溢出 错误!
import copy
def use_deepcopy():
a={'x':1,'y':2,'z':3}
b=[]
b.append(copy.deepcopy(a))
print("1a",a)
print ("1b",b)
a["x"]=5
print("2a",a)
print("2b",b)
b.append(a)
print("3a",a)
print("3b",b)
结果:
1a {'x': 1, 'y': 2, 'z': 3}
1b [{'x': 1, 'y': 2, 'z': 3}]
2a {'x': 5, 'y': 2, 'z': 3} a[x]改变了
2b [{'x': 1, 'y': 2, 'z': 3}] 在列表中的字典的a[x]没有改变,这是我们要的结果
3a {'x': 5, 'y': 2, 'z': 3}
3b [{'x': 1, 'y': 2, 'z': 3}, {'x': 5, 'y': 2, 'z': 3}]
法2:每次使用前都新建一个列
def new_dict():
a = {'x': 1, 'y': 2, 'z': 3}
b = []
b.append(a)
print("1a", a)
print("1b", b)
a = {'x': 1, 'y': 2, 'z': 3} # 这里重新生成了一个列表,虽然内容一样,但其实地址是不同的
a["x"] = 5 # 这里修改了a[x]影响到了上面的a列表,但被加入到b里面的那个a列表不会受到影响
print("2a", a)
print("2b", b)
b.append(a)
print("3a", a)
print("3b", b)
结果同上面一样。如果要保留a中的其他原值,则可以使用类似下面的函数来处理一下:
def _new_dict(old_dict:dict) -> dict:
new_dict={}
for v in old_dict.keys():
new_dict[v]=old_dict[v]
return new_dict
调用则可以类似:
a=_new_dict(a)