在处理列表和字典时,尽管传递引用常常是最方便的方法,但如果函数修改了
传入的列表或字典,你可能不希望这些变动影响原来的列表或字典。要做到这一点, Python 提供了名为 copy 的模块,其中包含 copy()和 deepcopy()函数。第一个函数
copy.copy(),可以用来复制列表或字典这样的可变值,而不只是复制引用。在交互式环境中输入以下代码:
>>> import copy
>>> spam = ['A', 'B', 'C', 'D']
>>> cheese = copy.copy(spam)
>>> cheese[1] = 42
>>> spam
['A', 'B', 'C', 'D']
>>> cheese
['A', 42, 'C', 'D']
现在 spam 和 cheese 变量指向独立的列表,这就是为什么当你将 42 赋给下标 7时,只有 cheese 中的列表被改变。在图 4-7 中可以看到,两个变量的引用 ID
数字不再一样,因为它们指向了独立的列表。
如果要复制的列表中包含了列表,那就使用 copy.deepcopy()函数来代替。deepcopy()函数将同时复制它们内部的列表。
4.8 小结
列表是有用的数据类型,因为它们让你写代码处理一组可以修改的值,同时仅
用一个变量。在本书后面的章节中,你会看到一些程序利用列表来完成工作。没有
列表,这些工作很困难,甚至不可能完成。
列表是可变的,这意味着它们的内容可以改变。元组和字符串虽然在某些方面
像列表, 却是不可变的, 不能被修改。包含一个元组或字符串的变量,可以被一个
新的元组或字符串覆写, 但这和现场修改原来的值不是一回事, 不像 append()和
remove()方法在列表上的效果。
变量不直接保存列表值,它们保存对列表的“引用”。在复制变量或将列表作
为函数调用的参数时,这一点很重要。因为被复制的只是列表引用,所以要注意,
对该列表的所有改动都可能影响到程序中的其他变量。如果需要对一个变量中的列
表修改,同时不修改原来的列表,就可以用 copy()或 deepcopy()。
4.9 习题
1.什么是[]?
2.如何将'hello'赋给列表的第三个值,而列表保存在名为 spam 的变量中?(假
定变量包含[2, 4, 6, 8, 10])。
对接下来的 3 个问题,假定 spam 包含列表['a', 'b', 'c', 'd']。
3. spam[int('3' * 2) / 11]求值为多少?
4. spam[-1]求值为多少?
5. spam[:2]求值为多少?
对接下来的 3 个问题。假定 bacon 包含列表[3.14, 'cat', 11, 'cat', True]。
6. bacon.index('cat')求值为多少?
7. bacon.append(99)让 bacon 中的列表值变成什么样?
8. bacon.remove('cat')让 bacon 中的列表时变成什么样?
9.列表连接和复制的操作符是什么?
10. append()和 insert()列表方法之间的区别是什么?
11.从列表中删除值有哪两种方法?
12.请说出列表值和字符串的几点相似之处。
13.列表和元组之间的区别是什么?
14.如果元组中只有一个整数值 42,如何输入该元组?
15.如何从列表值得到元组形式?如何从元组值得到列表形式?
16.“包含” 列表的变量,实际上并未真地直接包含列表。它们包含的是什么?
17. copy.copy()和 copy.deepcopy()之间的区别是什么?
4.10 实践项目
作为实践, 编程完成下列任务