Python中的嵌套列表

k3bvogb1  于 2023-11-15  发布在  Python
关注(0)|答案(5)|浏览(130)

我想复制一个2D列表,这样如果我修改一个列表,另一个列表就不会被修改。
对于一维列表,我只需要这样做:

a = [1, 2]
b = a[:]

字符串
现在如果我修改ba不会被修改。
但这对二维列表不起作用:

a = [[1, 2],[3, 4]]
b = a[:]


如果我修改ba也会被修改。
我该怎么弥补?

kkbh8khc

kkbh8khc1#

对于一个更通用的解决方案,无论维数如何,都可以使用copy.deepcopy()

import copy
b = copy.deepcopy(a)

字符串

55ooxyrt

55ooxyrt2#

b = [x[:] for x in a]

字符串

h6my8fg2

h6my8fg23#

为什么b = a[:]不能用于嵌套列表(或者说多维列表)?

a = [[1,2],[3,4]]
B = a[:]

答案:虽然当我们使用slicing[:]操作复制列表a时,但是内部子列表仍然引用列表b的内部子列表

  • 注意:我们可以在python中使用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]
    下面是所有可用复制方法的时间复杂度比较source
  1. 10.59秒(105.9us/itn)-copy.deepcopy(old_list)
  2. 10.16秒(101.6us/itn)-使用deepcopy复制类的纯python Copy()方法
  3. 1.488秒(14.88us/itn)-纯python Copy()方法不复制类(仅字典/列表/元组)
  4. 0.325秒(3.25us/itn)-for item in old_list: new_list.append(item)
  5. 0.217秒(2.17us/itn)-[i for i in old_list](列表理解)
  6. 0.186秒(1.86us/itn)-copy.copy(old_list)
  7. 0.075秒(0.75us/itn)-list(old_list)
  8. 0.053秒(0.53us/itn)-new_list = []; new_list.extend(old_list)
  9. 0.039秒(0.39us/itn)-old_list[:](列表切片)
oxf4rvwz

oxf4rvwz4#

对于二维嵌套数组,可以使用以下方法:B = [[y for y in x] for x in a]

vojdkbi0

vojdkbi05#

这是不工作的,因为当你做克隆或复制它会创建浅拷贝。那么什么是浅拷贝和深拷贝?
考虑一下,a是list,a = [1,2,3]现在当你创建新的name B= a[:]或B = a.copy().(两者都会给予相同的结果。).你需要了解在内存级别发生了什么。当我们创建copy时,list a & B的地址引用将被更改,因为在python中一切都是通过引用传递的。然而,列表中的项目地址将保持不变。请参阅下面的片段。
[创建列表并打印元素的id] 1
现在,我们将创建一个复制并打印复制对象中元素的id。
You can see after creating copy, id's of objects inside list has not changed.
但是,两个列表的ID将不同,如下所示:
[Id的不同] 3
这被称为浅拷贝,其中可变数据类型内的对象的地址不会改变。因此,如果您将可变数据类型传递到另一个可变数据类型(这只是2D列表)内,那么地址将与可变数据类型内的地址相同。因此,使用名称a所做的更改也将反映在b中。请参见下面的代码片段。
[2-D列表概述。] 4
如果你的要求是不应该有任何变化,那么你可以使用deepcopy作为下面的代码片段。
[Deep复制] 5

相关问题