Python - 复制列表
你好,有抱负的Python程序员们!今天,我们将深入探讨Python中复制列表的奇妙世界。作为你友好的邻居计算机科学老师,我将用清晰的解释、大量的例子,甚至可能途中穿插一两个笑话来引导你完成这次学习之旅。那么,让我们开始吧!
在Python中复制列表
在我们深入了解复制列表的不同方法之前,首先让我们理解一下为什么我们首先需要复制列表。想象一下,如果你有一个购物清单,想和你的室友分享。你可以把你的原始清单给他们,但如果他们决定在清单上加上“巧克力”(谁不会呢)?突然间,你精心计划的健康购物清单就被破坏了!这时,复制就派上用场了。
在Python中,当你将一个列表分配给一个新变量时,你并不是创建了一个新的列表。相反,你是创建了一个对同一个列表的新引用。让我们看看这是如何工作的:
original_list = [1, 2, 3, 4, 5]
new_list = original_list
print("原始列表:", original_list)
print("新列表:", new_list)
new_list.append(6)
print("修改后的原始列表:", original_list)
print("修改后的新列表:", new_list)
输出:
原始列表: [1, 2, 3, 4, 5]
新列表: [1, 2, 3, 4, 5]
修改后的原始列表: [1, 2, 3, 4, 5, 6]
修改后的新列表: [1, 2, 3, 4, 5, 6]
惊讶吗?两个列表都改变了,因为它们实际上是内存中的同一个列表。这时复制就来拯救了!
对Python列表进行浅复制
浅复制会创建一个新的列表对象,但新列表中的元素是对原始列表中相同对象的引用。这就像给你的购物清单做一个复印件——你有一张新的纸,但上面写的东西是一样的。
让我们看看如何创建一个浅复制:
import copy
original_list = [1, [2, 3], 4]
shallow_copy = copy.copy(original_list)
print("原始列表:", original_list)
print("浅复制:", shallow_copy)
shallow_copy[1][0] = '二'
print("修改后的原始列表:", original_list)
print("修改后的浅复制:", shallow_copy)
输出:
原始列表: [1, [2, 3], 4]
浅复制: [1, [2, 3], 4]
修改后的原始列表: [1, ['二', 3], 4]
修改后的浅复制: [1, ['二', 3], 4]
注意到改变浅复制中的嵌套列表也影响了原始列表吗?那是因为嵌套列表仍然是对内存中同一个对象的引用。
对Python列表进行深复制
另一方面,深复制会创建一个新的列表,并递归地添加嵌套对象的副本。这就像重新手写你的整个购物清单——一切都是全新的和独立的。
以下是创建深复制的做法:
import copy
original_list = [1, [2, 3], 4]
deep_copy = copy.deepcopy(original_list)
print("原始列表:", original_list)
print("深复制:", deep_copy)
deep_copy[1][0] = '二'
print("修改后的原始列表:", original_list)
print("修改后的深复制:", deep_copy)
输出:
原始列表: [1, [2, 3], 4]
深复制: [1, [2, 3], 4]
修改后的原始列表: [1, [2, 3], 4]
修改后的深复制: [1, ['二', 3], 4]
这次,修改深复制并没有影响原始列表。它是完全独立的!
使用切片表示法复制列表
现在,让我们看看复制列表的其他方法。最简单的方法之一是使用切片表示法。这就像说,“我想要从开始到结束的整个列表的副本。”
original_list = [1, 2, 3, 4, 5]
slice_copy = original_list[:]
print("原始列表:", original_list)
print("切片副本:", slice_copy)
slice_copy.append(6)
print("修改后的原始列表:", original_list)
print("修改后的切片副本:", slice_copy)
输出:
原始列表: [1, 2, 3, 4, 5]
切片副本: [1, 2, 3, 4, 5]
修改后的原始列表: [1, 2, 3, 4, 5]
修改后的切片副本: [1, 2, 3, 4, 5, 6]
这个方法创建了一个列表的浅副本,对于像数字和字符串这样的不可变对象的列表通常足够。
使用list()函数复制列表
创建副本的另一个方法是使用list()
函数。这就像告诉Python,“给我一个新的列表,看起来就像这个一样。”
original_list = [1, 2, 3, 4, 5]
list_copy = list(original_list)
print("原始列表:", original_list)
print("列表副本:", list_copy)
list_copy.append(6)
print("修改后的原始列表:", original_list)
print("修改后的列表副本:", list_copy)
输出:
原始列表: [1, 2, 3, 4, 5]
列表副本: [1, 2, 3, 4, 5]
修改后的原始列表: [1, 2, 3, 4, 5]
修改后的列表副本: [1, 2, 3, 4, 5, 6]
这个方法也创建了一个列表的浅副本。
使用copy()函数复制列表
最后但同样重要的是,我们有copy()
方法,这是列表的内置方法。就像列表在说,“这里,拿走我自己的副本!”
original_list = [1, 2, 3, 4, 5]
copy_method = original_list.copy()
print("原始列表:", original_list)
print("副本方法:", copy_method)
copy_method.append(6)
print("修改后的原始列表:", original_list)
print("修改后的副本方法:", copy_method)
输出:
原始列表: [1, 2, 3, 4, 5]
副本方法: [1, 2, 3, 4, 5]
修改后的原始列表: [1, 2, 3, 4, 5]
修改后的副本方法: [1, 2, 3, 4, 5, 6]
这个方法也创建了一个列表的浅副本。
现在,让我们用一个方便的表格来总结所有这些方法:
方法 | 语法 | 复制类型 | 备注 |
---|---|---|---|
赋值 | new_list = original_list |
引用 | 不是真正的副本 |
浅复制 | copy.copy(original_list) |
浅 | 新列表,相同的对象引用 |
深复制 | copy.deepcopy(original_list) |
深 | 新列表,新的对象引用 |
切片表示法 | original_list[:] |
浅 | 简单且易读 |
list()函数 | list(original_list) |
浅 | 清晰的意图 |
copy()方法 | original_list.copy() |
浅 | 列表的内置方法 |
记住,选择正确的复制方法取决于你的具体需求。如果你处理的是不可变对象的简单列表,浅复制通常就足够了。但是如果你有嵌套列表或可变对象,你可能需要一个深复制来确保完全独立。
现在,你已经有了复制列表的专业知识。下次你需要分享你的购物清单时,你会知道如何准确地制作一个副本,而不会面临任何意外的添加。快乐编码,愿你的列表总是完美复制!
Credits: Image by storyset