首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >填充列表--蟒蛇在做什么?

填充列表--蟒蛇在做什么?
EN

Stack Overflow用户
提问于 2014-10-05 04:29:00
回答 4查看 63关注 0票数 0

我想我已经解决了我自己的问题,但我正在寻求更好地理解原因,或者是开悟/开诚布公。

我有一份名单叫vec:

代码语言:javascript
复制
vec = [0.0, 0.0] 

它在读取数据时更改值。

为了比较当前和以前的值,我有另一个列表,我称之为oldvec。如果我将oldvec定义为

代码语言:javascript
复制
oldvec = vec

然后,每当vec改变值时,它就会改变值,所以比较是无用的--它们总是一样的。

但是,如果我改写

代码语言:javascript
复制
oldvec = [vv for vv in vec] 

我没有这个问题- oldvec保持它的值,即使vec变化,所以比较当前和以前的向量的工作,我需要它,即它实际上检测重复和非重复!为什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-10-05 12:23:52

您可以看到下面的情况的一种方法是使用id函数。这显示了对象的内存地址。内存地址是指将对象存储在物理内存中的位置。

如果我们为这三个命令运行它,并查看不同的地址(这就在我的计算机上,如果您自己运行它,您会得到不同的数字):

代码语言:javascript
复制
>>> vec = [0.0, 0.0]
>>> print id(vec)
4501729936

>>> oldvec1 = vec
>>> print id(oldvec1)
4501729936

>>> oldvec2 = [vv for vv in vec]
>>> print id(oldvec2)
4502046984

我们看到vecoldvec1引用相同的地址,因此它们是同一个对象的两个不同的标签。在这个框架下,Python在address 4501729936上操作对象:变量名称vecoldvec1只是我们可以使用的方便标签。它们没有提到“不同的”对象。

相比之下,oldvec2的位置完全不同。当Python运行列表理解时,它不知道这将产生与以前相同的列表,因此它创建了该列表的新副本。

这是一张快速的脏照片来显示正在发生的事情。虽然红色的博客和绿色的博客恰好包含相同的信息,但它们是两个不同的小块。vecoldvec1都指向同一个红色blob,因此对其中之一的任何操作都会影响底层的红色blob,并反映在另一个红色blob中。相反,oldvec2指向一个完全不同的绿色blob,它恰好是红色blob中信息的副本,但是对绿色blob的更改不会影响红色blob。

票数 1
EN

Stack Overflow用户

发布于 2014-10-05 04:38:05

将oldvec设置为vec可以使oldvec指向vec。您还没有创建一个新的列表,您只是为它创建了另一个名称。通过使用列表理解,您将显式创建列表的新副本,相当于vec.copy()。

票数 1
EN

Stack Overflow用户

发布于 2014-10-05 04:37:49

在Python中,变量是“引用”,这意味着可以有两个变量引用同一个对象。在您的第一个例子中,这就是正在发生的事情:同一个列表的两个名称。

如果您需要第二个实际列表,可以“复制”第一个列表。有关方法,请参见此处:How to clone or copy a list?

请注意,这也适用于列表中的项--如果它们是更复杂的对象,您可以选择对列表进行“深度复制”,复制每个元素的每个部分,或者复制一个“浅拷贝”,只复制引用,这样就会有一个包含对原始对象的新引用的新列表。您需要为每个用例选择正确的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26199620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档