
6-8 列表的复制
6-8-1 列表复制deep copy
假设我喜欢的运动是篮球与棒球,可以用下列方式设置列表。
mysports=['basketball','baseball']
如果我的朋友也是喜欢这两种运动,读者可能会想用下列方式设置列表。
friendsports=mysports
程序实例ch6_35.py:列出我和朋友所喜欢的运动。

执行结果

初看上述执行结果好像没有任何问题,可是如果我想加入美式足球football当作喜欢的运动,我的朋友想加入传统足球soccer当作喜欢的运动,这时我喜欢的运动如下。
basketball、baseball、football
我朋友喜欢的运动如下。
basketball、baseball、soccer
程序实例ch6_36.py:继续使用ch6_35.py,加入美式足球football当作喜欢的运动,我的朋友想加入传统足球soccer当作喜欢的运动,同时列出执行结果。

执行结果

这时获得的结果,不论是我和我的朋友喜欢的运动都相同,football和soccer都变成两人共同喜欢的运动。类似这种只要有一个列表更改元素就会影响到另一个列表同步更改的复制过程称为深度复制。
6-8-2 地址的概念
可以使用id()函数获得变量的地址,可参考下列语法。
id(x)
上述语句可以获得变量x的地址。对于列表而言,如果使用下列方式设置两个列表变量相等,相当于只是将变量地址复制给另一个变量。
friendsports=mysports
上述语句相当于是将mysports变量地址复制给friendsport。所以程序实例ch6_36.py在执行时,两个列表变量所指的地址相同,所以新增运动项目时,都是将运动项目加在同一变量地址,可参考下列实例。
程序实例ch6_37.py:重新设计ch6_36.py,增加列出列表变量的地址。

执行结果

由上述执行结果可以看到,使用程序第3行设置列表变量相等时,实际只是将列表地址复制给另一个列表变量。
6-8-3 列表的复制shallow copy
浅复制(shallow copy)的思想是,执行复制后当一个列表改变后,不会影响另一个列表的内容,这是本节的重点。方法应该如下。
friendsports=mysports[ : ]
程序实例ch6_38.py:使用浅复制方式,重新设计ch6_36.py。下列是与ch6_36.py之间唯一不同的程序代码。

执行结果

由上述执行结果可知,我们已经获得了两个列表彼此是不同的列表地址,同时也得到了想要的结果。