Python列表不反映variables的变化

当我写这个代码:

polly = "alive" palin = ["parrot", polly] print(palin) polly = "dead" print(palin) 

我以为会输出这个:

 "['parrot', 'alive']" "['parrot', 'dead']" 

但是,它不。 我如何得到它输出?

Pythonvariables保存对值的引用。 因此,当你定义palin列表时,你传入polly引用的值,而不是variables本身。

您应该将值想象成气球,variables是线程绑定到这些气球。 "alive"是一个气球, polly只是一个线程,而palin列表有一个不同的线程绑定到同一个气球。 在Python中,列表仅仅是一系列线程,全部从0开始编号。

你接下来要做的是把pollystring绑定到一个新的"dead"气球上,但是这个链表仍然保留着和"alive"气球绑定的旧线程。

你可以把这个线程replace为列表中的"alive" ,方法是通过索引重新分配列表来引用每个线程; 在你的例子中是线程1

 >>> palin[1] = polly >>> palin ['parrot', 'dead'] 

在这里,我简单地把palin[1]线绑在一起, polly与同样的东西绑在一起,不pipe可能如何。

请注意,Python中的任何集合,例如dictsettuple等等都只是线程的集合。 其中一些可以将线程交换出来用于不同的线程,比如列表和字典,这就是python“mutable”中的一些东西。

另一方面,string是不可变的。 一旦你定义了一个像"dead""alive"的string,它就是一个气球。 你可以用一个线程(一个variables,一个列表或任何其他)绑定它,但是你不能replace它里面的字母。 你只能将该线程绑定到一个全新的string。

python中的大部分事情可以像气球一样。 整数,string,列表,函数,实例,类,都可以绑定到一个variables,或捆绑成一个容器。

您也可以阅读Ned Batchelder关于Python名称的论文 。

在您的第二个打印语句之前,将您的新值存储到palin

 palin = ["parrot", polly] 

当你把一个string放在一个列表中时,这个列表保存了一个string的副本。 string最初是一个variables,一个字面值,一个函数调用的结果,还是其他的东西都没有关系。 在列表看到它时,它只是一个string值。 稍后更改生成的string不会影响列表。

如果你想存储一个值的引用,当这个值发生变化的时候,通常的机制就是使用一个包含“引用”值的列表。 把这个应用到你的例子中,你得到了一个嵌套的列表:

 polly = ["alive"] palin = ["parrot", polly] print(palin) polly[0] = "dead" print(palin) 

该列表将只包含值,而不是您想要的variables的引用。 然而,你可以在列表中存储一个lambdaexpression式,并使lambdaexpression式查找variables的值。

 >>> a = 'a' >>> list = ['a',lambda: a] >>> list[1] <function <lambda> at 0x7feff71dc500> >>> list[1]() 'a' >>> a = 'b' >>> list[1]() 'b' 

你不能。 分配给一个裸名是Python总是只重新绑定名字,并且你不能自定义或者监视这个操作。

你可以做的是使polly变成一个可变的对象而不是一个string,并改变它的值,而不是重新命名的名称。 一个简单的例子:

 >>> polly = ['alive'] >>> items = ['parrot', polly] >>> items ['parrot', ['alive']] >>> polly[0] = 'dead' >>> items ['parrot', ['dead']] 

其他答案已经解释了发生了什么事情。

这是激励使用对象的(几个)问题之一。 例如,可以这样做:

 class Animal: def __init__(self, aniType, name): self.aniType = aniType self.name = name self.isAlive = True def kill(self): self.isAlive = False def getName(self): return self.name def getType(self): return self.aniType def isLiving(self): return self.isAlive polly = Animal("parrot", "polly") print(polly.getName()+' the '+polly.getType()+' is alive?') print(polly.isLiving()) polly.kill() print(polly.getName()+' the '+polly.getType()+' is alive?') print(polly.isLiving()) 

对于一个简单的任务来说,它可能看起来像很多代码,但对象往往是这样的事情的方式,因为它们有助于保持一切的组织。

这是该程序的输出:

 polly the parrot is alive? True polly the parrot is alive? False