【问题标题】:How to assign another list to a list "passed by reference"? [duplicate]如何将另一个列表分配给“通过引用”的列表? [复制]
【发布时间】:2019-05-23 05:19:57
【问题描述】:

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

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

当我在被调用者中更改列表的一个特定元素时,它在调用者中是可观察的。这是什么类型的传递,按值调用还是按引用调用?我不相信,我也很感激对此的任何澄清。

【问题讨论】:

  • This answer 可能涵盖您正在寻找的内容。
  • 强烈推荐阅读nedbatchelder.com/text/names.html 问题是“作业”会覆盖您之前发送的任何内容。如果你想改变原始对象,你必须使用对象的方法,例如l.clear()

标签: python list pass-by-reference


【解决方案1】:

您只是在callee 范围内重新分配了一个局部变量。 因此,只需更改该列表的内容即可:

def callee(l):
  l[:] = list()
  # or l.clear()

【讨论】:

    【解决方案2】:

    您正在更改引用,而不是修改引用的对象。要查看差异,您需要实际更改通过引用传递的对象:

    def callee(l):
        while len(l) > 0:
            l.pop()
    
    
    
    def caller():
        l = [1, 2, 3]
        callee(l)
        print(l) # prints [] 
    

    【讨论】:

      【解决方案3】:

      每次使用 = 运算符时,您都在更改变量指向的对象。

      当你输入时

      l = [1, 2, 3]
      

      在内存中创建了一个 python 列表,在 caller() 范围内名为 l 的引用现在指向这个新创建的列表。

      但是,当调用 callee() 函数时,会在内存中创建另一个列表,现在它在 callee() 范围内有一个引用指向它。

      所以现在我们在内存中有 2 个列表(而不是一个),每个列表都有自己的引用指针(在两种情况下都命名为 l,但在不同的范围内)。当 callee() 返回时,对第二个列表的引用过期并且对象现在没有更多指向它的指针,因此垃圾收集器将其从内存中删除。原始列表保持不变。

      要清除列表,您可以使用l.clear()。由于您没有使用= 运算符,因此不会在内存中创建新对象,您可以确定您指向的是同一个旧对象。

      【讨论】:

        猜你喜欢
        • 2012-06-24
        • 1970-01-01
        • 1970-01-01
        • 2017-10-29
        • 2021-06-22
        • 1970-01-01
        • 1970-01-01
        • 2017-07-11
        • 2023-01-13
        相关资源
        最近更新 更多