为什么python在定义函数时会这样对待列表?

为什么python在定义函数时会这样对待列表?,python,python-3.x,list,variables,Python,Python 3.x,List,Variables,我正在编写一个代码,变量开始表现出奇怪的行为,并被分配到我认为不应该的事情上。因此,我决定将情况简化到最低程度,以解决我的疑问,事情就是这样发生的: 以下代码: 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 = 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)
行为正常(如我所料)


编辑:此问题被视为重复的。我不认为这是真的,因为函数中过程的局部性字符被破坏也与此相关。

在Python中,名称指的是值,所以有两个名称指向相同的值。

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

在版本1中,您创建一个列表
a
,将其传递给化名
c
下的函数,为同一列表创建另一个化名
d
,然后更改该列表中的第一个值<代码>a、
c
d
都指向同一个列表


在第2版中,您使用的是
list(c)
,在Python中,这意味着“获取名为
c
的可移植内容,并从中创建一个名为
d
的新的、不同的列表”。现在,你的名单上有两份副本。一个称为
a
c
,另一个称为
d
。因此,当您更新
d[0]
时,您正在操作列表的第二个副本
a
保持不变。

在版本1中,您创建一个列表
a
,将其传递到化名
c
下的函数,为同一列表创建另一个化名
d
,然后更改该列表中的第一个值<代码>a、
c
d
都指向同一个列表


在第2版中,您使用的是
list(c)
,在Python中,这意味着“获取名为
c
的可移植内容,并从中创建一个名为
d
的新的、不同的列表”。现在,你的名单上有两份副本。一个称为
a
c
,另一个称为
d
。因此,当您更新
d[0]
时,您正在操作列表的第二个副本<代码>a保持不变。

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

让我们看看下面的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]

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

让我们看看下面的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]

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

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

在第二个示例中,复制
c
(即
a
)的值,并将其赋给新变量
d

因此
d
现在与
c
(即
a
)具有相同的值,但引用不同

注意:您可以使用
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)

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

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

在第二个示例中,复制
c
(即
a
)的值,并将其赋给新变量
d

因此
d
现在与
c
(即
a
)具有相同的值,但引用不同

注意:您可以使用
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)

因为当你这样做的时候:

 d = list(c)
这将创建一个新对象。但当你这么做的时候

d = c
您正在引用该对象

如果是的话

d.append(5)
到第一个例子,你会得到

[10,5]
与第二个操作相同,列表未修改


在下面的链接中有更深入的解释:

这是因为当您这样做时:

 d = list(c)
这将创建一个新对象。但当你这么做的时候

d = c
您正在引用该对象

如果是的话

d.append(5)
到第一个例子,你会得到

[10,5]
与第二个操作相同,列表未修改


在下面的链接中有更深入的解释:

'd=c'表示前面所述的参考副本。这意味着,现在d将引用与c相同的对象。在对被引用对象执行直接操作时,a引用的对象的值也会更改


当您执行'd=list(c)'时,这意味着将创建一个新的list对象,并使用c。但是,d不再引用与a相同的对象。因此,函数内的更改不会影响a。

'd=c'表示前面所述的参考副本。这意味着,现在d将引用与c相同的对象。在对被引用对象执行直接操作时,a引用的对象的值也会更改


当您执行'd=list(c)'时,这意味着将创建一个新的list对象,并使用c。但是,d不再引用与a相同的对象。因此,函数中的更改不会影响a。

d=c
不会生成新列表。参见
d=c
只是说“名称
c
引用的对象现在是reference