首页 > 解决方案 > .pop 从列表中删除项目会导致 python 中的变量范围出现奇怪的问题

问题描述

这让我非常疯狂,所以任何帮助将不胜感激。我有一个程序,我正在迭代函数中的列表。这是问题的玩具模型:

masterList = ["person","woman","man","camera","television"]
workingList = masterList

def removeItem (workingList):
    item = workingList.pop(2)
    print("Test 1:",workingList)


removeItem(workingList)

print("Test 2:", workingList)
print("Test 3:", masterList)

正如预期的那样,“测试 1”打印出删除了一个项目的列表。
但是,“测试 2”也会打印出删除了一个项目的列表。我没想到会这样,但没关系。这不是真正的问题,但我确信这里有一些关于变量范围和变量阴影的东西我不明白。

没有真正的问题是“测试 3”,如您所见,它正在打印列表,甚至不应该被removeItem函数或其中的pop函数触及。然而,它也打印出删除了一个项目的列表。

这怎么可能发生,我该如何预防?

非常感谢!

干杯,阿里

标签: pythonscopepycharmglobal-variablesshadowing

解决方案


Python 列表是可变对象。

m = list([1, 2, 3])
n = m

a = 5
b = a

id(a) == id(b)
# id() return "identity" of the object.
# True,  Both a and b are references to the same object. 
id(m) == id(n)
# True,  Both m and n are references to the same object. 

b = b + 2 
id(a) == id(b)
# False, a new object on separate location is created, which b will point.

n.pop()
id(m) == id(n)
# True, the object is mutated, and m and n still references to the same object.

因为,python 列表是可变的,m 和 n 在突变后仍然会引用同一个对象。而对于像 int 这样的不可变对象,将创建一个新对象,并且标识符将引用新对象。

要点是,在您的场景中,由于 python 列表是可变的,因此只有一个对象。

但是,如果在修改新列表时需要保持原列表不变,可以使用 copy() 方法。

new_list = original_list.copy()

new_list和的 idoriginal_list不同。

在此处详细了解可变性:https ://medium.com/@meghamohan/mutable-and-immutable-side-of-python-c2145cf72747 。


推荐阅读