如何将另一个列表分配给列表"passed by reference"?
How to assign another list to a list "passed 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
如何在被调用函数中删除列表的所有元素?
当我更改被调用者列表中的一个特定元素时,它在调用者中是可见的。这是哪种传递,按值调用还是按引用调用?我不相信,我也很欣赏对此的任何澄清。
您正在更改引用,而不是修改引用的对象。要查看差异,您需要实际更改通过引用传递的对象:
def callee(l):
while len(l) > 0:
l.pop()
def caller():
l = [1, 2, 3]
callee(l)
print(l) # prints []
您只是在 callee
的范围内重新分配一个局部变量。
因此,只需更改该列表的内容即可:
def callee(l):
l[:] = list()
# or l.clear()
每次使用 =
运算符时,您都在更改变量指向的对象。
当您键入时
l = [1, 2, 3]
在内存中创建了一个 python 列表,caller() 范围内名为 l 的引用现在指向这个新创建的列表。
但是,当调用 callee() 函数时,会在内存中创建另一个列表,现在它在 callee() 范围内有一个指向它的引用。
所以现在我们在内存中有 2 个列表(而不是一个),每个列表都有自己的引用指针(在两种情况下都命名为 l,但在不同的范围内)。当 callee() returns 时,对第二个列表的引用过期并且该对象现在没有更多指向它的指针,因此垃圾收集器将其从内存中删除。原列表保持不变。
要清除列表,您可以使用l.clear()
。由于您没有使用 =
运算符,因此不会在内存中创建新对象,您可以确定您指向的是同一个旧对象。
据信 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
如何在被调用函数中删除列表的所有元素?
当我更改被调用者列表中的一个特定元素时,它在调用者中是可见的。这是哪种传递,按值调用还是按引用调用?我不相信,我也很欣赏对此的任何澄清。
您正在更改引用,而不是修改引用的对象。要查看差异,您需要实际更改通过引用传递的对象:
def callee(l):
while len(l) > 0:
l.pop()
def caller():
l = [1, 2, 3]
callee(l)
print(l) # prints []
您只是在 callee
的范围内重新分配一个局部变量。
因此,只需更改该列表的内容即可:
def callee(l):
l[:] = list()
# or l.clear()
每次使用 =
运算符时,您都在更改变量指向的对象。
当您键入时
l = [1, 2, 3]
在内存中创建了一个 python 列表,caller() 范围内名为 l 的引用现在指向这个新创建的列表。
但是,当调用 callee() 函数时,会在内存中创建另一个列表,现在它在 callee() 范围内有一个指向它的引用。
所以现在我们在内存中有 2 个列表(而不是一个),每个列表都有自己的引用指针(在两种情况下都命名为 l,但在不同的范围内)。当 callee() returns 时,对第二个列表的引用过期并且该对象现在没有更多指向它的指针,因此垃圾收集器将其从内存中删除。原列表保持不变。
要清除列表,您可以使用l.clear()
。由于您没有使用 =
运算符,因此不会在内存中创建新对象,您可以确定您指向的是同一个旧对象。