在 Python 中复制嵌套列表
- 2024-12-19 09:23:00
- admin 原创
- 75
问题描述:
我想复制一个二维列表,这样如果我修改一个列表,另一个列表就不会被修改。
对于一维列表,我只需这样做:
a = [1, 2]
b = a[:]
现在如果我修改b
,a
则不会被修改。
但这对于二维列表不起作用:
a = [[1, 2],[3, 4]]
b = a[:]
如果我修改b
,a
也会被修改。
我该如何修复这个问题?
解决方案 1:
对于无论维数多少都能起作用的更通用的解决方案,请使用copy.deepcopy()
:
import copy
b = copy.deepcopy(a)
解决方案 2:
b = [x[:] for x in a]
解决方案 3:
这b = a[:]
对于嵌套列表(或者说多维列表)不起作用?
a = [[1, 2],[3, 4]]
b = a[:]
答案a
:虽然当我们使用操作复制列表时slicing[:]
,但内部子列表仍然引用列表的内部子列表注意:我们可以在 python 中使用b
检查引用id()
。让我们用一个例子来理解。
>>> 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]
。
将 2D 列表复制到另一个列表时,它会添加对它的引用,而不是实际列表。
相反,您可以使用:
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.extens[a]
以下是所有可用复制方法的时间复杂度比较(来源)
10.59 秒 (105.9us/itn) -
copy.deepcopy(old_list)
10.16 秒 (101.6us/itn) - 纯 Python
Copy()
方法使用 deepcopy 复制类1.488 秒 (14.88us/itn) - 纯 Python
Copy()
方法不复制类 (仅字典/列表/元组)0.325 秒 (3.25us/itn) -
for item in old_list: new_list.append(item)
0.217 秒 (2.17us/itn)-
[i for i in old_list]
(列表推导)0.186 秒 (1.86us/itn) -
copy.copy(old_list)
0.075 秒 (0.75us/itn) -
list(old_list)
0.053 秒 (0.53us/itn) -
new_list = []; new_list.extend(old_list)
0.039 秒 (0.39us/itn) -
old_list[:]
(列表切片)
解决方案 4:
对于二维嵌套数组,可以使用以下方法:b = [[y for y in x] for x in a]
解决方案 5:
它不起作用,因为当你进行克隆或复制时,它会创建浅拷贝。那么什么是浅拷贝和深拷贝?
假设 a 是列表,a = [1,2,3],现在当您创建新名称 b= a[:] 或 b = a.copy() 时。(两者都会给出相同的结果。)您需要了解内存级别发生了什么。当我们创建副本时,列表 a 和 b 的地址引用将发生变化,因为在 python 中一切都是通过引用传递的。但是,列表中项目的地址将保持不变。请参阅下面的代码片段。
[创建列表并打印元素的 ID]
1
现在,我们将创建一个副本并打印复制对象内的元素的 id。
您可以看到,创建副本后,列表内的对象的 id 没有改变。
然而,两个列表的 ID 将会有所不同,如下所示:
[ID 不同]
3
这称为浅拷贝,其中可变数据类型内的对象的地址不会改变。因此,如果您将可变数据类型传递到另一个可变数据类型(只不过是二维列表)中,则地址将与可变数据类型内部的地址相同。因此,使用名称 a 所做的更改也将反映在 b 中。请参阅下面的代码片段。
[二维列表概览。]
4
如果您的要求是不应当有任何改变,那么您可以使用 deepcopy ,如下面的代码片段所示。
[深层复制]
5
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件