如何在不复制对象的情况下将var添加到Python列表中?

时间:2014-09-23 19:17:54

标签: python list object reference

我试图用Python完成一些事情,但我无法在互联网上找到关于此的信息,所以这是我的问题。

拥有此示例代码:

a = 5
b = [a]

我需要b [0]作为a的指针引用。目前如果我做

b[0] = 7

a.var仍然是5,如果我将值设置为b [0],则保持不变。

我想知道Python中是否有任何方法可以在不复制数据的情况下将Object存储在数组中,所以如果我修改了一个,我也会修改另一个。

编辑一个

我想更清楚地说明我想要完成的事情,也许我能找到真正的答案。

我有一个像

这样的自定义类
class Foo(object):
    def __init__(self):
        self.var = 7

我还有一个这样的列表:

myList = [Foo()]

我真正的问题在于:

在代码的某个地方,我需要做以下任务:

self.foo = myList[0]

然后,当我尝试访问此foo var时,我注意到它从未从原始实例更新。基本上这就是我需要的。

编辑两个

所有答案都是正确的。在我的赋值的每一步使用id(var)我可以验证Object始终是相同的,因此错误必须在其他地方。感谢所有人的帮助,我希望这篇文章可以帮助其他人。

3 个答案:

答案 0 :(得分:5)

您已经存储了对象,即整数5.您未存储的是名称a和值5之间的名称 - 值绑定。您的问题是操作b[0] = 7不会修改对象5;它只修改b[0]与其值(从5到7)之间的绑定,保持值本身(5和7)不受影响。实际上,你不能修改值5,因为5是一个整数,Python中的整数是不可变的。

另一种说法是b[0] = 7不会修改b[0]引用的对象;相反,它修改了b引用的对象。 b是一个列表,列表是内部跟踪其索引所指向的对象的对象。当你执行b[0] = 7时,这会告诉b"在这个新对象"上设置你的0索引点。它没有"通知" b[0]现在指向它们的5(旧值)或7(新值)。 Python中的对象不知道哪种引用指向它们;他们只知道他们指的是什么(如果有的话)。

您要求的不是存储对象的方式,而是存储"变量" ---即本地命名空间中的名称与值之间的绑定。答案是,通常没有办法在Python中执行此操作。没有任何构造允许你b = something(a),所以当你以后做b[0] = 8时,会改变。

如果您希望能够修改名称 - 值绑定,则需要更改a,使其成为可以更改其内容的某种对象,而不是仅仅使其成为普通变量。例如,如果你这样做:

a = [5]
b = a
b[0] = 7

然后你会发现a也发生了变化。对于其他类型的对象也是如此:如果将a设置为其属性可以更改的其他类型的对象,然后您就地更改其属性,那么这些更改将显示出来你如何引用这个对象。

您可能会发现阅读Python变量的工作方式很有帮助,例如在this articlethis one中。

答案 1 :(得分:3)

您是否可以执行此操作取决于您的列表元素是否为immutable or mutable types。不可变类型无法更改,因此当您重新分配一个不可变的变量时,它实际上会创建一个新对象并使用相同的标签对其进行标记。可以更改可变类型,因此可以在不重新分配基础对象的情况下更改它。

例如,假设a是一个列表,这是一个可变类型。

a = [5]
b = [a]
a[0] = 3
print(b)
# [[3]]

a.append('hi')
print(b)
# [[3, 'hi']]

您的测试代码实际上以您希望的方式运行,因为objects are mutable

class Object():
    pass

a = Object()
a.var = 5

b = [a]
b[0].var = 7

print(a.var)
# 7

出于同样的原因,您的其他示例代码仍然可以正常工作。当我指定a = l[0]时,它不会复制任何内容,而只是为a引用的对象创建附加引用l[0]

l = [Object() for _ in range(5)]
l[0].var = 5

a = l[0]
l[0].var = 7

print(a.var)
# 7

答案 2 :(得分:1)

你写

  

a = 5

     

b = [a]

     

我需要b [0]作为指向。

的指针

你做不到。您可以使a指向可变对象并更改该对象的值:

class Object(object): 
    '''an object'''

a = Object()
a.value = 5
b = a
b.value = 7

现在a.value返回:

7

同样,但这次有一个清单:

a = [5]
b = a
b[0] = 7

现在a[0]是:

7