在Python中复制嵌套列表

Sup*_*ing 38 python copy list deep-copy

我想复制一个2D列表,这样如果我修改一个列表,另一个列表就不会被修改.

对于一维列表,我只是这样做:

a = [1, 2]
b = a[:]
Run Code Online (Sandbox Code Playgroud)

现在,如果我修改b,a不修改.

但这不适用于二维列表:

a = [[1, 2],[3, 4]]
b = a[:]
Run Code Online (Sandbox Code Playgroud)

如果我修改b,a也会被修改.

我该如何解决?

Aym*_*ieh 52

对于无论维数多少都可以使用的更通用的解决方案,请使用copy.deepcopy():

import copy
b = copy.deepcopy(a)
Run Code Online (Sandbox Code Playgroud)

  • "命名空间是一个很棒的主意 - 让我们做更多的事情吧!" (5认同)
  • @Dav,你提出了一个有效的观点.我更喜欢总是导入模块以避免名称冲突,而不是逐个处理函数.:) (2认同)
  • 请注意,这还将深度复制列表中的实际元素。 (2认同)

Ign*_*ams 50

b = [x[:] for x in a]
Run Code Online (Sandbox Code Playgroud)

  • 适当时+1.我个人喜欢避免复制/深度复制(在现实生活中很少有一个有效的用例;对于一个超过2维的imo列表也是如此) (6认同)

Tus*_*har 7

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

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

答案a:虽然当我们使用 using操作复制列表时slicing[:],但内部子列表仍然引用 list 的内部子列表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
Run Code Online (Sandbox Code Playgroud)

因此,切片不会更改列表内对象的引用。 您可以从上面注意到 的引用a[0]与 相同b[0]
当您将二维列表复制到另一个时,它会添加对其的引用,而不是实际列表。

相反,您可以使用:

  • 乙 =copy.deepcopy(a)
  • 乙 =[item[:] for item in a]
  • 乙 =[item.copy() for item in a]
  • 乙 =[list(item) for item in a]
  • 乙 =[copy.copy(item) for item in a]
  • 乙 =[]; b.extens[a]

下面是所有可用复制方法的时间复杂度比较来源

  1. 10.59 秒(105.9us/itn)- copy.deepcopy(old_list)

  2. 10.16 秒 (101.6us/itn) - 纯 pythonCopy()方法用 deepcopy 复制类

  3. 1.488 秒 (14.88us/itn) - 纯 pythonCopy()方法不复制类(仅字典/列表/元组)

  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[:]列表切片