复制列表(或多数内置的可变集合),最简单的方式是使用内置的类型构造方法
l1 = [1,2,3]
l2 = list(l1)
l3 = l1[:]
l2
和 l3
实现的效果是一样的, 但是这种复制只是浅复制.即只复制了最外层容器,副本中的元素是源容器元素的引用. 如果有可变的元素(如列表嵌套列表),就会产生问题.
l1 = [3, [6, 5, 4], (7, 8, 9)]
l2 = list(l1)
l1.append(100)
l1[1].remove(5)
print('l1', l1)
print('l2', l2)
l2[1] += [33, 22]
l2[2] += (10, 11)
print('l1', l1)
print('l2', l2)
l1 [3, [6, 4], (7, 8, 9), 100]
l2 [3, [6, 4], (7, 8, 9)]
l1 [3, [6, 4, 33, 22], (7, 8, 9), 100]
l2 [3, [6, 4, 33, 22], (7, 8, 9, 10, 11)]
通过此网址的交互式demo可以看到它的状态如下:
l1
添加100对于l2
没有影响
l1
删除列表中的元素时,因为列表是可变的对象,l2
中的值也会改变,这是因为他们指向同一个地址,副本共享内部对象的引用.
l2
增加元组中的元素时,对l1
没有影响,这是因为元祖是不可变的,+=
运算符相当于重新创建了一个新的元组.
为任意对象做深浅复制
class Bus:
def __init__(self, passengers = None):
if passengers is None:
self.passengers = []
else:
self.passengers =list(passengers)
def pick(self, name):
self.passengers.append(name)
def drop(self, name):
self.passengers.remove(name)
import copy
bus1 = Bus(['alice', 'bill', 'claire', 'david'])
bus2 = copy.copy(bus1)
bus3 = copy.deepcopy(bus1)
id(bus1), id(bus2), id(bus3)
(140419270432584, 140419270432640, 140419270432864)
bus1.drop('bill')
bus2.passengers
bus3.passengers
['alice', 'claire', 'david']
['alice', 'bill', 'claire', 'david']
id(bus1.passengers), id(bus2.passengers), id(bus3.passengers)
(140419339067656, 140419339067656, 140419279593672)