如何将另一个列表分配给“通过引用传递”的列表?

时间:2018-12-23 19:55:58

标签: python list pass-by-reference

我们相信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

如何在被调用方函数中删除列表的所有元素?

当我在被叫方中更改列表的一个特定元素时,在调用方中可以观察到。按值调用或按引用调用是什么类型的传递?我相信两者都不对,我也对此表示感谢。

3 个答案:

答案 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()。由于您没有使用=运算符,因此不会在内存中创建任何新对象,并且可以确保您指向的是同一旧对象。