在介绍深拷贝和浅拷贝时,先看一个循环删除list,导致下标错误的案例
#循环删除list导致下标错误 a = [1,1,2,3,4,5] #下标:0 1 2 3 4 5 原始 #[1,2,3,4,5] 第一次循环 # 0 1 2 3 4 #[1,2,4,5] 第二次循环,第二次循环后会从新的list中的下标为1开始循环,因为下标为0的已经循环过了,1会保留下来 # 0 1 2 3 for i in a: if i % 2!=0: a.remove(i) #输出结果:[1, 2, 4]
那么该如何解决这个问题呢,可以操作两个相同的list ,一个list用来循环,另外一个用来删除,就不会引起下标出错了
a = [1,1,2,3,4,5] a1 = [1,1,2,3,4,5] for i in a1: if i % 2!=0: a.remove(i) print(a) #输出结果:[2,4]
深拷贝、浅拷贝
深拷贝需要调用copy模块,只有唯一的一个方法 copy.deepcopy()。
深拷贝:是将某个内容在内存开辟一个新的存储空间来存储,这样即使改变原来的内容,深拷贝的内容也不会变化
浅拷贝:是将某个内容重新复制给一个新的变量,这个变量和原来的变量都指向同一个内存地址,所有只要原来的内容一变化,浅拷贝的内容也会发生相应变化
注意:内存地址不变,一定是浅拷贝,但是内存地址发生变化,不一定是深拷贝,需要修改下原数据来验证拷贝后的数据是否发生变化
测试下深 浅拷贝的例子
import copy a = ['12',2,3,4,{'key':'key1'}] a2 = a a3 = copy.deepcopy(a) a4 = a.copy() a.pop(1) a[-1]['key1'] = 'liangcailian' print(a2) print('a3',a3) print('a4',a4)
关于深拷贝的一个类中的应用:
import random class User: def __init__(self,id,status): self.id = id self.status = status class Order: def __init__(self,id,status): self.id = id self.status = status users = [] orders = [] u_fail_count = 0 for i in range(20): u = User(i,random.choice(['fail','succes'])) o = Order(i,random.choice(['fail','succes'])) orders.append(o) users.append(u) print('失败的个数',u_fail_count) print('成功的个数',20 - u_fail_count ) def delete_item(items): items2 = copy.deepcopy(items) for item in items2: if item.status == 'fail': items.remove(item) return items # result = delete_item(users) # print(len(result))