为什么在函数中修改列表会改变原来的列表,但在函数中声明会创建一个新的对象?

问题描述 投票:0回答:2

我是写代码的新手,我对列表的行为有一定的了解。每当一个列表在函数的作用域内被修改时,全局作用域内的列表也会发生变化。

比如说

def modify_list(lst):
    lst.append(5)

lst = [1, 2, 3, 4]

#This output is [1, 2, 3, 4]
print(lst)

modify_list(lst)

#This output is [1, 2, 3, 4, 5] because of the function.
print(lst)

我不明白为什么这个例子不能用。

def modify_list(lst):
    lst = [1, 2, 3, 4, 5]

lst = [1, 2, 3, 4]

#Output is [1, 2, 3, 4]
print(lst)

modify_list(lst)

#Output is [1, 2, 3, 4]
print(lst)

为什么 lst 在第二个例子中被修改?是不是因为我在函数的作用域内创建了一个新对象?使用全局关键字可以代替传递参数,但我想避免使用全局,除非绝对必要。

我在一个初始化函数中使用这个函数,并且希望在每次调用函数时将列表恢复到原始状态。同样,使用全局也可以,我只是想知道为什么这个不能工作。(如果我不善于解释的话,抱歉)

python list function parameters mutable
2个回答
0
投票

列表中的 id 函数在这里派上了用场。基本上, id 函数返回一个整数,这个整数保证在任何对象的生命周期内都是唯一的和恒定的。事实上,在CPython(常规Python)中。id 返回内存中对象的地址。

所以,如果你运行你的代码,打印出了 lst 运行前后 modify_list你会发现,当你分配给 lst 但当你追加时却不是。

调用append在 lst 不会改变 lst 因为Python中的列表是 可变,并简单地附加 变种 列表。但是,当你将 [1, 2, 3, 4, 5]lst列表对象,您将创建一个全新的列表对象并将其分配给 lst. 这不是突变,无论如何也不会改变原件。一般来说,在 Python 中,你可以在一个函数中突变参数来修改原来的副本,但是给它赋一个新的对象并不是突变,也不会改变原来的副本。


0
投票

def modify_list(lst):
    lst = [1, 2, 3, 4, 5]

你让本地变量 lst 指向的对象与你在 modify_list(lst) 呼叫。也许这篇文章能帮助你理解。https:/medium.comschool-of-codeepassing-by-assignment-in-python-7c829a2df10a。

© www.soinside.com 2019 - 2024. All rights reserved.