列表是python里面很重要的内置数据结构,而列表也十分的常见。列表可以说是一个由有顺序的可以索引的元素组成的可变的线性数据结构。那么在使用列表中我们可能需要对一个原列表进行不同的操作,这样我们就需要使用不同的复制手段来解决需求问题。那么列表复制到底有什么不同的呢?
首先,我们这里有一个很简单的列表,如下:
list1 = [1,2,3,4]
如果我们把list1直接赋值给一个新的列表;list2,并将list2里面的 索引为2的元素重新赋值那么会对原来的列表产生影响吗?
list1 = [1,2,3,4]
list2 = list1
list2[2] = 8
print(list1)
[1, 2, 8, 4]
我们可以看到改变list2对list1也产生了影响。这种赋值是完全一样的,动其中一个剩下的那个也会发生改变。那么怎么只复制内容?
list2 = list1.copy()
id(list1),id(list2)
(79456904, 81130696)
可以通过内存的ID看到两个列表的地址是不一样的,也不会产生像直接赋值那样的互相影响。但是如果列表里面的元素有引用型的元素呢?同样使用list.copy()还可以吗?
list0 = [1,2,[3,4],5]
list3 = list0.copy()
list3[1] = 8
list3[2][1] = 9
print(list0)
print(list3)
[1, 2, [3, 9], 5]
[1, 8, [3, 9], 5]
我们可以看到list0里面的第3个元素[3,4]是一个复杂型的数据,它不像是单独的一个数,字符串那样。这时通过copy list3其实只是浅复制或者叫影子复制,这时处理引用型数据就会对原来的列表产生影响一起改变,因为复制时只是复制了内存的地址,新的地址通往的还是原来的内存中存放的引用类型。
一般复制时我们肯定不想对原来的列表产生影响,那么我们就需要深拷贝了。copy模块提供了deepcopy。
import copy
list0 = [1,2,[3,4],5]
list4 = copy.deepcopy(list0)
list4[2][1] = 9
print(list0)
print(list4)
[1, 2, [3, 4], 5]
[1, 2, [3, 9], 5]
可以看到使用深拷贝即使原列表有引用类型,也是不会互相影响的。