Python__学习路上的坑之--引用,浅拷贝,深拷贝
copy : 相当于只是拷贝表面一层,如果里面还有深层次的引用,那么也是直接拷贝引用的地址,而且如果拷贝对象是不可变类型比如元组,那么也是直接拷贝引用.
deepcopy: 无论是拷贝可变类型还是不可变类型,无论是里面嵌套了多深层次的引用关系,统统复制一份,在新的空间中存储起来.
之前在廖雪峰老师的网站上看到一个练习题,输出杨辉三角,一位同学这么写的:
import copy def triangles(): L = [1] while True: yield L #L = L.copy() L.append(0) L = [L[i-1]+L[i] for i in range(len(L))]
思路没问题,但是,他这样问:copy那步,无论是否注释,输出一样,可是一注释就会测试失败,可输出没问题,怎么回事?
因为之前了解过引用,浅拷贝,深拷贝,所以肯定是防止append内存地址和别的东西冲突,但是我测试了一看,输出没问题啊,那是怎么肥四?
廖雪峰老师为了方便同学调试代码,在网站上直接做了个输入代码的地方,只要在本机用脚本开端口,就可以直接在网站上调试代码,输出结果,他的测试结果对错的代码是这样的:
# 期待输出: # [1] # [1, 1] # [1, 2, 1] # [1, 3, 3, 1] # [1, 4, 6, 4, 1] # [1, 5, 10, 10, 5, 1] # [1, 6, 15, 20, 15, 6, 1] # [1, 7, 21, 35, 35, 21, 7, 1] # [1, 8, 28, 56, 70, 56, 28, 8, 1] # [1, 9, 36, 84, 126, 126, 84, 36, 9, 1] n = 0 results = [] for t in triangles(): print(t) results.append(t) <----------------------------------------------------------------------------------------------------------- n = n + 1 if n == 10: break if results == [ [1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1], [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56, 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1] ]: print('测试通过!') else: print('测试失败!')
append ....对,你没有看错,从生成器中取出一个值t,直接append加到results里面去了,导致如果生成器里面对列表L和t一样内存地址的元素进行操作,则直接影响到results里面的结果.
如果不加L=L.copy()这一句的的话,生成器里面L.append(0),则results里面对应的元素也加个0 - -