Python - 复制列表

你好,有抱负的Python程序员们!今天,我们将深入探讨Python中复制列表的奇妙世界。作为你友好的邻居计算机科学老师,我将用清晰的解释、大量的例子,甚至可能途中穿插一两个笑话来引导你完成这次学习之旅。那么,让我们开始吧!

Python - Copy Lists

在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