Python 3.x 当列表处于列表状态时,使用list.pop()函数
我在理解以下代码时遇到问题: 下面是我编写的一个示例:Python 3.x 当列表处于列表状态时,使用list.pop()函数,python-3.x,list,Python 3.x,List,我在理解以下代码时遇到问题: 下面是我编写的一个示例: listA=[] listB=[] listA.append(10) print(listA) listB.append(listA) print(listB) listA.pop() print(listA) print(listB) 我希望shell打印出以下结果: [10] [[10]] [] [[10]] 但实际上我得到的是: [10] [[10]] [] [[]] 我不明白这背后的逻辑。如果我将代码更改为: listA=[]
listA=[]
listB=[]
listA.append(10)
print(listA)
listB.append(listA)
print(listB)
listA.pop()
print(listA)
print(listB)
我希望shell打印出以下结果:
[10]
[[10]]
[]
[[10]]
但实际上我得到的是:
[10]
[[10]]
[]
[[]]
我不明白这背后的逻辑。如果我将代码更改为:
listA=[]
listB=[]
listA.append(10)
print(listA)
listB.append(listA)
print(listB)
listA=[]
print(listA)
print(listB)
这会达到我的预期。
我希望有人能告诉我为什么这两个代码给出不同的结果,但代码的作用是相同的?您感到困惑的原因是
Python
列表是可变的
,而不是不可变的
数据类型,如字符串。这意味着它们是通过引用传递的,而不是通过值传递的
所以当你打电话时:
listB.append(listA)
您没有将列表a
的内容作为列表添加到列表B
,而是将引用传递到列表a
在内存中的位置
这意味着当您使用pop()
从listA
中删除10
时,您正在更改listA
在内存中的位置。因此,当您打印列表B
时,它会查找列表A
的参考
,发现它没有任何内容(当您弹出列表10
)时,会打印一个空的列表
在第二个
代码
中,您做了一些不同的事情(即它们与您所说的不同)。在这里,您不必从listA
中pop
调用10
,而是通过执行以下操作将名为listA
的变量重新分配给空列表
:
listA = []
这会产生不同的结果,因为使用[10]
的前一个列表a
的引用仍然保留在列表B
中。因此,当您修改变量
listA
时,您将为它分配一个新的内存块
,它将在那里存储其内容。同时,带有[10]
的旧内存块保持不变,因此listB
保持不变为[[10]]
您感到困惑的原因是Python
列表是可变的
,而不是不可变的
数据类型,如字符串
。这意味着它们是通过引用传递的,而不是通过值传递的
所以当你打电话时:
listB.append(listA)
您没有将列表a
的内容作为列表添加到列表B
,而是将引用传递到列表a
在内存中的位置
这意味着当您使用pop()
从listA
中删除10
时,您正在更改listA
在内存中的位置。因此,当您打印列表B
时,它会查找列表A
的参考
,发现它没有任何内容(当您弹出列表10
)时,会打印一个空的列表
在第二个
代码
中,您做了一些不同的事情(即它们与您所说的不同)。在这里,您不必从listA
中pop
调用10
,而是通过执行以下操作将名为listA
的变量重新分配给空列表
:
listA = []
这会产生不同的结果,因为使用[10]
的前一个列表a
的引用仍然保留在列表B
中。因此,当您修改变量
listA
时,您将为它分配一个新的内存块
,它将在那里存储其内容。同时,带有[10]
的旧内存块保持不变,因此listB
保持不变,因为[[10]]
变量(在python中)类似于句柄listA
只是列表实际所在位置的句柄。
您组装了一个如下所示的结构,其中箭头表示“指向”:
然后,在第一种情况下,通过调用pop()
将10
取出。但它仍然是同一个盒子,因此它看起来像这样:
但是,在第二种情况下,您所做的只是将句柄重新分配给一个新列表[]
:
变量(在python中)类似于句柄listA
只是列表实际所在位置的句柄。
您组装了一个如下所示的结构,其中箭头表示“指向”:
然后,在第一种情况下,通过调用pop()
将10
取出。但它仍然是同一个盒子,因此它看起来像这样:
但是,在第二种情况下,您所做的只是将句柄重新分配给一个新列表[]
:
由于您在listB中保存了对listA的引用并修改了listA,所以如果您打印它,listB也会发生变化!?对于预期的结果,您必须复制或克隆列表,而不保留引用。那么,这是否意味着如果我尝试执行示例中的操作,我将无法使用堆栈函数?因为您在listB中保存对listA的引用并修改listA,如果您打印它,listB也会更改!?对于预期的结果,您必须复制或克隆列表,而不保留引用。那么,这是否意味着如果我尝试执行示例中的操作,则无法使用堆栈函数?