在 Python 中复制嵌套列表
Posted
技术标签:
【中文标题】在 Python 中复制嵌套列表【英文标题】:Copying nested lists in Python 【发布时间】:2011-02-02 06:25:19 【问题描述】:我想复制一个二维列表,这样如果我修改一个列表,另一个不会被修改。
对于一维列表,我只是这样做:
a = [1, 2]
b = a[:]
现在如果我修改b
,a
不会被修改。
但这不适用于二维列表:
a = [[1, 2],[3, 4]]
b = a[:]
如果我修改b
,a
也会被修改。
我该如何解决这个问题?
【问题讨论】:
很多时候,当人们使用嵌套列表并需要以这种方式复制它们时,他们真的很想使用numpy
。
恕我直言,这只是语言中的一个错误。对于应该相同的两种情况,行为是不同的——解释语言的典型行为。如果你有大代码,很难调试
@SerhiiPoklonskyi 不,这不是错误。当您执行b = a[:]
时,您会创建一个新列表b
,因此例如a.append([5, 6])
不会修改b
,因为它只会更改a
。但是,a[1][0] = 5
行将更改b
,因为它更改了b
引用的列表。
@ArtemisFowl 对我不起作用(a[1][0] 也不会修改 b)。即使会,我也不明白这有什么关系。问题是:当您执行a = b.copy()
时,a
成为内存中的一个单独位置:既不是引用也不是指向b
的指针,即它是一个自变量。但是,如果您这样做 a = b.copy()
并且 b
是一个数组,那将不起作用。这怎么可能有任何合乎逻辑的解释?如果b
是一个数组,a = b.copy()
必须创建一个自变量。否则这是一个错误。 p.s.无意无礼,如果我错了,请向我解释
@SerhiiPoklonskyi 我认为您感到困惑的原因是您误解了 Python。 Python 实际上并没有这样的“二维数组”,它只有列表,可以包含其他列表。我将尝试通过一个示例来演示:您将a
定义为a = [[1, 2], [3, 4]]
。然后创建a
的副本:b = a.copy
。这是一个不同的列表,但它包含相同的“子列表”,这意味着更改b
,例如b.append([5, 6])
不会更改a
,但是更改b
中的列表,例如b[0].append(3)
还将更改a
的第一个列表。
【参考方案1】:
b = [x[:] for x in a]
【讨论】:
适当时+1。我个人喜欢避免复制/深度复制(在现实生活中很少有有效的用例;对于超过 2 维 imo 的列表也可以这样说) 你能提供一个用例吗?我正在尝试复制 2D 列表,但我不确定用您提供的变量名称替换什么。 @JohnLockeb
是新列表,a
是旧列表。 x
内部使用。
对我来说,path
是一个二维数组,我想复制 path[i]
所以我做了curr_level = [x[:] for x in path[i]]
这就是我所说的高效(和聪明)编程! (导入额外的模块来做一些没有它们就可以完成的事情是低效的。)【参考方案2】:
对于更通用的解决方案,无论维度数量如何,请使用copy.deepcopy()
:
import copy
b = copy.deepcopy(a)
【讨论】:
@Dav,你的观点很有道理。我更喜欢总是导入模块以避免名称冲突,而不是逐个处理函数。 :) 请注意,这也会对列表中的实际元素进行深度复制。 @Dav,我不同意,通常最好使用 module.function() 格式。 “命名空间是一个很棒的主意——让我们做更多这样的事!” @FogleBird:但是,PEP-8 实际上似乎暗示from ... import ...
是规范,除非存在命名空间冲突:python.org/dev/peps/pep-0008(参见“Imports”)。以上是关于在 Python 中复制嵌套列表的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 2 中,无论列表的内容如何,如何按值而不是引用复制复杂嵌套元素的列表