从列表构造列表是否保证可以复制?

问题描述 投票:0回答:1

我有一些Python代码需要一个可迭代的(列表或元组或生成器表达式或任何其他可迭代的),并且需要将其复制到一个新列表中。

以下作品:

newlist = [x for x in olditerable]

但我想知道我是否可以这样做:

newlist = list(olditerable)

显然,如果 olditerable 是不是列表,它会按要求工作(制作副本)。 不太明显的是,当 olditerable is 列表时,它似乎也可以按要求工作(制作副本):

oldlist = [1,2,3]
newlist = list(oldlist)
assert newlist is not oldlist  # so it didn't just return oldlist
oldlist.append("appended to oldlist")
newlist.append("appended to newlist")
print(f"oldlist is {oldlist}")
print(f"newlist is {newlist}")

输出进一步确认newlist不是oldlist:

oldlist is [1, 2, 3, 'appended to oldlist']
newlist is [1, 2, 3, 'appended to newlist']

这种复制行为有保证吗? 我无法以某种方式找到任何有关它的文档。

相比之下,

tuple(oldtuple)
确实制作副本(当然,因为这样做很愚蠢,因为元组是不可变的):

oldtuple = (1,2,3)
newtuple = tuple(oldtuple)
assert newtuple is oldtuple
python
1个回答
0
投票

来自文档

构造函数构建一个列表,其项目相同且位于相同的位置 作为 iterable 的项目排序。 iterable 可以是一个序列,一个 支持迭代的容器,或者迭代器对象。如果可迭代 已经是一个列表,创建并返回一个copy,类似于

iterable[:]
。例如,
list('abc')
返回
['a', 'b', 'c']
并且
list( (1, 2, 3) )
返回
[1, 2, 3]
。如果没有给出参数,则 构造函数创建一个新的空列表,
[]

文档在这里没有明确说明的是类型构造函数

list()
执行浅复制。这意味着虽然列表对象本身是新的,但它的元素不会被复制,而是被引用。如果您的列表包含可变对象(如其他列表或字典),则对新列表中的这些对象的修改将影响原始列表:

>>> oldlist = [[1, 2], [3, 4]]
>>> newlist = list(oldlist)
>>> newlist[1].append(5)
>>> oldlist
[[1, 2], [3, 4, 5]]
>>> newlist
[[1, 2], [3, 4, 5]]
>>> newlist.append(6)
>>> oldlist
[[1, 2], [3, 4, 5]]
>>> newlist
[[1, 2], [3, 4, 5], 6]
© www.soinside.com 2019 - 2024. All rights reserved.