在下面的代码中,为什么w
在从v
弹出5
后仍然保留5
?将扩展在Python中创建一个新副本
>>> w = [1,2,3]
>>> v = [4,5]
>>> w.extend(v)
>>> w
[1, 2, 3, 4, 5]
>>> v
[4, 5]
>>> v.pop()
5
>>> v
[4]
>>> w
[1, 2, 3, 4, 5]
在下面的代码中,为什么w
在从v
弹出5
后仍然保留5
?将扩展在Python中创建一个新副本
>>> w = [1,2,3]
>>> v = [4,5]
>>> w.extend(v)
>>> w
[1, 2, 3, 4, 5]
>>> v
[4, 5]
>>> v.pop()
5
>>> v
[4]
>>> w
[1, 2, 3, 4, 5]
列表的extend
方法,接受一个迭代(不仅仅是另一个列表),并延伸与来自可迭代的所有项的列表。
官方Python文档:
通过附加来自可迭代的所有项目扩展列表。等同于[len(a):] =可迭代。
这是比其他迭代手动迭代较短方式,并且append
他们原始列表:
v = [1,2,3]
w = [4,5]
for i in w:
v.append(i)
这意味着所涉及的项目的基准被从可迭代复制到原始列表,因此稍后修改迭代器(列表w
)不会影响原始列表(v
)。
要说清楚,这不会改变iterable
项目本身的易变性/不可变性。因此,如果来自w
的项目是可变的,那么它们在被追加到v
(复制参考)后将保持可变。
这是错误的或至少是误导性的。使用扩展时不会复制任何内容。通过执行这个带有可变对象列表的例子来检查自己,然后通过访问其中一个列表来对它们进行变异。 – timgeb
如果第二个迭代中的可变项目被复制,则对它们的引用被复制。因此改变可变项目将反映所有参考。问题是,如果调用'extend'将保持与第二个'list'(传递给'extend')的任何关联,并且我的答案指出答案是否定的,因为“extend”参数不一定是'列表“(可变)。它可以是任何'iterable'(比如一个字符串),所以'extend'方法本身不会保留对迭代器的引用,而是复制它的项目。 – farzad
是的,但扩展不会在可变对象和不可变对象之间产生任何差异。使用'list.extend'时不会复制任何对象。这就是为什么我在编辑帖子之前抱怨过。 – timgeb
整数1,2,3,4,5是的某处在内存中并且w
指向w.extend(v)
之后的所有这些整数。您通过pop
方法从v
中删除最后一个参考文件的事实不会改变这一点。
extend
将对象引用添加到列表中。在w.extend(v)
之后,这两个列表都引用v
中的项目。 v.pop()
删除了v
的参考文献,但它仍然在w
。一旦你扩展了一个列表,从其他容器添加或删除并不重要....这就是引用计数的全部内容。
而不是尴尬地描述的情况,为什么不张贴代码或解释会话,告诉我们发生了什么和输出不同于你的预期?请给我 – timgeb
[mcve]。你在和我们玩捉迷藏。 –