Python列表不反映变量

时间:2012-08-22 20:01:42

标签: python list variables

当我写这段代码时:

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

我认为它会输出:

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

然而,它没有。如何输出它?

6 个答案:

答案 0 :(得分:48)

Python变量包含对的引用。因此,当您定义palin列表时,您传入polly引用的值,而不是变量本身。

您应该将值想象为气球,变量是与这些气球相关联的线程。 "alive"是一个气球,polly只是该气球的一个主题,而palin列表中有一个不同的主题与该气球相关联。在python中,列表只是一系列线程,所有线程都从0开始编号。

您接下来要做的是将polly字符串绑定到新的气球"dead",但该列表仍然保留与"alive"气球相关的旧线程。

您可以通过索引重新分配列表来将该线程替换为列表持有的"alive"以引用每个线程;在你的例子中是线程1

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

在这里,我简单地将palin[1]线程绑定到与polly绑定的相同的东西,无论可能是什么。

请注意,python中的任何集合,例如dictsettuple等,也只是线程的集合。其中一些可以将它们的线程换成不同的线程,例如列表和dicts,这就是使python中的某些内容“可变”的原因。

另一方面,字符串可变。定义类似"dead""alive"的字符串后,它就是一个气球。你可以用线程(变量,列表或其他)绑定它,但你不能替换它内部的字母。您只能将该线程绑定到完全字符串。

python中的大多数东西都可以像气球一样。整数,字符串,列表,函数,实例,类都可以绑定到变量,或绑定到容器中。

您也可以阅读Ned Batchelder's treatise on Python names

答案 1 :(得分:4)

在第二个打印声明之前,将新值存储到palin

palin = ["parrot", polly]

答案 2 :(得分:4)

将字符串放入列表时,列表会保存字符串的副本。字符串最初是变量,文字值,函数调用的结果还是其他内容并不重要;当列表看到它时,它只是一个字符串值。更改之后生成字符串的任何内容都不会影响列表。

如果要存储对该值发生变化时会注意到的值的引用,通常的机制是使用包含“引用”值的列表。将其应用于您的示例,您最终会使用嵌套列表。例如:

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

答案 3 :(得分:1)

列表仅包含值,而不是您想要的变量引用。但是,您可以在列表中存储lambda,并让lambda查找变量的值。

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

答案 4 :(得分:0)

你做不到。对裸名称的赋值是Python始终只重新绑定名称,并且您无法自定义或监视此操作。

您可以做的是使polly成为可变对象而不是字符串,并改变其值而不是重新绑定名称。一个简单的例子:

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

答案 5 :(得分:0)

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

这是激发对象使用的(几个)问题之一。例如,有人可能会这样做:

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