Python列表变量不是通过引用传递的吗?

Python列表变量不是通过引用传递的吗?,python,list,Python,List,我对Python中的pass-by-ref和pass-by-value感到困惑。 在下面的代码中,当listB=listA时,应将指针(引用)分配给listA变量中的列表。对listB的任何更改都应反映在listA上。然而,在我的测试中并非如此。我的代码有问题吗?我正在运行Python 3.4.3 >>> listA = [1,2,3] >>> listB = listA >>> listA = [4,5,6] >>> pr

我对Python中的pass-by-ref和pass-by-value感到困惑。 在下面的代码中,当
listB=listA
时,应将指针(引用)分配给listA变量中的列表。对listB的任何更改都应反映在listA上。然而,在我的测试中并非如此。我的代码有问题吗?我正在运行Python 3.4.3

>>> listA = [1,2,3]
>>> listB = listA
>>> listA = [4,5,6]
>>> print(listA, listB)
[4, 5, 6] [1, 2, 3]
>>> listB[0] ='new'
>>> print(listA, listB)
[4, 5, 6] ['new', 2, 3]

当您执行
listA=[4,5,6]
时,对
listA
(分配给
listB
)的引用不再指向
listA
,因为您用新列表完全替换了
listA

listB[0] = 'new'

如果删除该行,您将发现它可以正常工作。

您将重新分配
listA
,因此它与
listB
之间没有关系

例如:

listA = [2,2,3]

listB = listA

id(listA)
Out[6]: 90404936

id(listB)
Out[7]: 90404936

listA[0]=2

id(listA)
Out[9]: 90404936

listB
Out[10]: [2, 2, 3]
但是,当您重新分配
listA
时,您将丢失该
id

listA = [3,3,3]

id(listA)
Out[12]: 92762056
但是
listB
保持相同的id:

id(listB)
Out[13]: 90404936
你说:

我对python中的pass-by-ref和pass-by-value感到困惑

实际上Python既不使用按值调用也不使用按引用调用:它使用。这基本上类似于按值调用,只是所讨论的“值”实际上是对保存实际值的对象的引用


从根本上讲,在Python中考虑变量的方式是它们实际上是值,而不是值本身。

对于Python,将名称空间看作是由一个列有名称和地址的2列表实现的。另外,请注意,赋值运算符
=
使右侧求值,如果尚未表示,则在内存中表示,然后使赋值左侧的变量在符号表中绑定到表示的地址。一次执行一行代码:

listA = [2, 3, 4]
使2、3和4在内存中以特定地址表示。然后,括号使一个列表对象在内存中表示,类的地址、长度的int和元素的地址数组。最后,名称
listA
被放置在名称空间表中,并绑定到该列表对象的地址

listB = listA
在名称空间表中创建第二个条目
listB
,并将其绑定到列表的相同地址

listA = [4, 5, 6]
在内存中创建三个int和一个列表的表示,并更改名称空间表中listA引用的地址,将其绑定到新列表

listB[0] = 'new'
使字符串“new”在内存中表示,然后更改绑定到
listB
的列表对象,使该列表的第一个元素现在引用字符串的地址


如果未将
listA
重新分配给新对象,它仍将指向相同的列表,并且无论是使用
listA
还是
listB
标记,您都会在列表的第一个元素中看到相同的更改。

您正在重新分配
listA
,因此,它不再指向与
listB
相同的值,有很多关于Python执行模型的好文章。