在Python中复制嵌套列表
我想复制一个二维列表,这样如果我修改一个列表,另一个列表就不会受到影响。
对于一维列表,我只需要这样做:
a = [1, 2]
b = a[:]
现在如果我修改了 b
,a
就不会被修改。
但是对于二维列表,这种方法就不行了:
a = [[1, 2],[3, 4]]
b = a[:]
如果我修改了 b
,a
也会被修改。
我该怎么解决这个问题呢?
5 个回答
为什么 b = a[:]
对嵌套列表(或者说多维列表)不起作用?
a = [[1, 2],[3, 4]]
b = a[:]
回答: 虽然我们用 slicing[:]
操作来复制列表 a
,但里面的子列表仍然指向列表 b
中的子列表。
注意:我们可以用 id() 来检查引用在 Python 中的情况。
让我们通过一个例子来理解。
>>> a = [[1,2],[3,4]]
>>> id(a)
140191407209856 # unique id of a
>>> b=a
>>> id(b)
140191407209856
>>> b=a[:] # Copying list a to b with slicing
>>> id(b)
140191407209920 # id of list b changed & is not same as id of list a
>>> id(a[0])
140191407188544
>>> id(b[0])
140191407188544
>>> id(a[0])==id(b[0]) # id of both a[0] & b[1] is same.
True
所以,切片操作不会改变列表内部对象的引用。
你可以从上面看到,a[0]
的引用和 b[0]
是一样的。
当你把一个二维列表复制到另一个列表时,它添加的是对这个列表的引用,而不是实际的列表。
相反,你可以使用:
- b =
copy.deepcopy(a)
- b =
[item[:] for item in a]
- b =
[item.copy() for item in a]
- b =
[list(item) for item in a]
- b =
[copy.copy(item) for item in a]
- b =
[]; b.extend(a)
下面是所有可用复制方法的时间复杂度比较(来源)
10.59秒 (105.9微秒/次) -
copy.deepcopy(old_list)
10.16秒 (101.6微秒/次) - 纯 Python
Copy()
方法复制类时使用 deepcopy1.488秒 (14.88微秒/次) - 纯 Python
Copy()
方法不复制类(仅复制字典/列表/元组)0.325秒 (3.25微秒/次) -
for item in old_list: new_list.append(item)
0.217秒 (2.17微秒/次) -
[i for i in old_list]
(一个 列表推导式)0.186秒 (1.86微秒/次) -
copy.copy(old_list)
0.075秒 (0.75微秒/次) -
list(old_list)
0.053秒 (0.53微秒/次) -
new_list = []; new_list.extend(old_list)
0.039秒 (0.39微秒/次) -
old_list[:]
(列表切片)
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,尤其是当我们刚开始学习编程的时候。比如,有人可能会在使用某个功能时,发现它没有按照预期工作,这时候就需要去查找原因。
通常,我们可以通过查看文档、搜索网上的资料,或者在像StackOverflow这样的社区提问来找到解决办法。在这些平台上,很多经验丰富的程序员会分享他们的经验和解决方案,这对初学者来说非常有帮助。
记住,遇到问题是学习编程的一部分,重要的是要保持耐心,积极寻找解决方案。随着时间的推移,你会逐渐掌握更多的知识和技能。
b = [x[:] for x in a]
如果你想要一个更通用的解决方案,不管数据有多少维度,都可以使用 copy.deepcopy()
:
import copy
b = copy.deepcopy(a)