我们相信python中的列表作为可变对象是通过引用传递的。但是,当我尝试更改传递给要由另一个列表(尤其是空列表)分配的功能的列表时,在调用者中观察不到该更改。
在这里提供更多详细信息是我的代码:
def callee(l):
l = list() # this could be any list but my interest was empty list
def caller():
l = [1, 2, 3]
caller(l)
print(l) # prints [1, 2, 3] while I expect an empty list
如何在被调用方函数中删除列表的所有元素?
当我在被叫方中更改列表的一个特定元素时,在调用方中可以观察到。按值调用或按引用调用是什么类型的传递?我相信两者都不对,我也对此表示感谢。
答案 0 :(得分:4)
您只是在callee
范围内重新分配了局部变量。
因此,只需更改该列表的内容即可:
def callee(l):
l[:] = list()
# or l.clear()
答案 1 :(得分:3)
您要更改引用,而不是修改引用的对象。要了解差异,您需要实际更改通过引用传递的对象:
def callee(l):
while len(l) > 0:
l.pop()
def caller():
l = [1, 2, 3]
callee(l)
print(l) # prints []
答案 2 :(得分:1)
每次使用=
运算符时,您都在更改变量指向的对象。
键入时
l = [1, 2, 3]
在内存中创建了一个python列表,并且在名为l的caller()范围内的引用现在指向此新创建的列表。
但是,当调用callee()函数时,会在内存中创建另一个列表,现在该列表在callee()范围内有一个指向它的引用。
因此,现在我们在内存中有2个列表(而不是一个),每个列表都有自己的引用指针(在两种情况下都以l命名,但作用域不同)。当callee()返回时,对第二个列表的引用到期,并且该对象现在不再有指向它的指针,因此垃圾收集器将其从内存中删除。原始列表保持不变。
要清除列表,可以使用l.clear()
。由于您没有使用=
运算符,因此不会在内存中创建任何新对象,并且可以确保您指向的是同一旧对象。