为什么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