0

我正在编写代码,变量开始表现得很奇怪,并被分配给我认为它们不应该分配的东西。因此,我决定将情况降低到最小的复杂性以解决我的疑问,这就是发生的事情:

以下代码:

a = [2]

def changeA(c):
    d = c
    d[0] = 10
    return True

changeA(a)

print(a)

打印“[10]”。这对我来说没有意义,因为在第一次分配之后我从未将列表“a”分配为任何内容。在函数 changeA 内部,局部变量 d 被分配为函数的输入,在我看来,这种分配是双向发生的,甚至改变了“外部”。如果是这样,为什么?如果不是,为什么会这样?

我还注意到代码

a = [2]

def changeA(c):
    d = list(c)
    d[0] = 10
    return True

changeA(a)

print(a)

表现正常(即,如我所料)。

编辑:这个问题被认为是这个问题的重复。我不认为这是真的,因为这里也涉及到函数内部过程的局部性特征被违反了。

4

6 回答 6

2

Python 变量是对对象的引用,有些对象是可变的。数字不是,字符串和元组也不是,但列表、集合和字典是。

让我们看看下面的 Python 代码

a = [2]       # ok a is a reference to a mutable list
b = a         # b is a reference to the exact same list
b[0] = 12     # changes the value of first element of the unique list
print(a)      # will display [12]
于 2018-05-31T21:51:07.317 回答
1

在第一个示例中,您只需将c(即a) 的引用传递给d.

所以无论你做什么d都会发生在a.

在第二个示例中,您复制c(which is a) 的值并将其赋予一个新变量d

所以now 与(which is )d具有相同的值,但引用不同。ca

注意:id()您可以使用该函数查看变量的引用或 id 。

a = [2]
print id(a)

def changeA(c):
    d = c
    pirnt id(d)
    d[0] = 10
    return True

changeA(a)

print(a)


a = [2]
print id(a)
def changeA(c):
    d = list(c)
    print id(d)
    d[0] = 10
    return True

changeA(a)

print(a)
于 2018-05-31T21:51:55.257 回答
1

这是因为当你这样做时:

 d = list(c)

这会创建一个新对象。但是当你这样做时

d = c

您正在引用该对象。

如果你这样做了

d.append(5)

第一个例子,你会得到

[10,5]

与第二个相同的操作并且列表没有被修改。

以下链接中有更深入的解释:http: //henry.precheur.org/python/copy_list

于 2018-05-31T21:53:03.553 回答
0

在 Python 中,名称指的是值,因此您有 2 个名称指向同一个值。

于 2018-05-31T21:44:22.290 回答
0

在版本 1 中,您创建一个 list a,将其传递给 pseudonym 下的函数,为同一个列表c创建另一个假名d,然后更改该列表中的第一个值。 a, c, 和d都指的是同一个列表。

在版本 2 中,您使用list(c)的是 Python,它的意思是“获取这个名为的可迭代事物的内容,c并从中创建一个新的、不同的列表,命名为d”。现在,您的列表有两个副本浮动。一种称为aor c,另一种称为d。因此,当您更新时,d[0]您正在操作列表的第二个副本。 a保持不变。

于 2018-05-31T21:50:52.140 回答
0

'd=c' 表示如前所述的参考副本。这意味着,现在 d 将引用与 c 相同的对象。当您对引用的对象进行直接操作时,a 所引用的对象的值也会发生变化。

当您执行 'd = list(c)' 时,这意味着创建了一个新的列表对象,其中包含 c 的烘焙。但是, d 不再引用与 a 相同的对象。因此,函数内的更改不会影响 a。

于 2018-05-31T21:57:48.467 回答