Python; 修改函数内的列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22054698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
python; modifying list inside a function
提问by roberto
Suppose I have function with list parameter, and inside its body I want to modify passed list, by copying elements of an array to the list:
假设我有一个带有 list 参数的函数,并且在它的主体内部我想修改传递的列表,方法是将数组的元素复制到列表中:
def function1 (list_arg):
a = function2() #function2 returns an array of numbers
list_arg = list(a)
list1 = [0] * 5
function1(list1)
list1
[0,0,0,0,0]
When doing it like this, it doesn't work. After executing function1(list1), list1remains unchanged. So, how to make function1return list1with the same elements (numbers) as array a?
当这样做时,它不起作用。执行后function1(list1),list1保持不变。那么,如何function1返回list1与数组相同的元素(数字)a?
采纳答案by Alfe
If you assign something to the variable list_arg, it will from then on point to the new value. The value it pointed to beforethat assignment (your original list) will stay unchanged.
如果你给变量赋值list_arg,它就会指向新的值。它在该分配之前指向的值(您的原始列表)将保持不变。
If you, instead, assign something to elementsof that list, this will change the original list:
相反,如果您为该列表的元素分配某些内容,这将更改原始列表:
list_arg[:] = list(a)
This will make your code work as you wanted it.
这将使您的代码按照您的意愿工作。
But keep in mind that in-place changes are hard to understand and probably can confuse the next developer who has to maintain your code.
但请记住,就地更改很难理解,并且可能会使下一个必须维护您的代码的开发人员感到困惑。
回答by tom10
You can operate on the list to change its values (eg, append something to it, or set its values) but changes will be reflected outside of the function only if you operate on the reference to the passed in object:
您可以对列表进行操作以更改其值(例如,向其添加某些内容或设置其值),但只有在对传入对象的引用进行操作时,更改才会反映在函数之外:
def function1 (list_arg):
list_arg.append(5)
If you have questions when doing this, print out the ids:
如果您在执行此操作时有任何疑问,请打印出ids:
def function1 (list_arg):
print 1, id(list_arg)
list_arg[:] = ["a", "b", "c"]
print 2, id(list_arg)
list_arg = range(10)
print 3, id(list_arg)
x = [1,2,3]
function1(x)
print x
prints:
印刷:
1 4348413856
2 4348413856
3 4348411984
['a', 'b', 'c']
That is, xis changed in place, but assigning to the function's local variable list_arghas no impact on x, because is then just assigns a different object to list_arg.
也就是说,x就地更改,但分配给函数的局部变量list_arg对 没有影响x,因为它只是将不同的对象分配给list_arg。
回答by Geoff Genz
You're changing a reference to a local variable. When you pass in list_arg this way:
您正在更改对局部变量的引用。当您以这种方式传入 list_arg 时:
def function1 (list_arg):
list_arg is a reference to an underlying list object. When you do this:
list_arg 是对底层列表对象的引用。当你这样做时:
list_arg = list(a)
You're changing what list_arg means within the function. Since the function exits right after that, list_arg = list(a) has no effect.
您正在更改 list_arg 在函数中的含义。由于该函数在此之后立即退出,因此 list_arg = list(a) 无效。
If you want to actually change the reference to the list you have to do assign it to the result of the function.
如果要实际更改对列表的引用,则必须将其分配给函数的结果。
def function1 ():
'a = some array'
return list(a)
list1 = [0] * 5
list1 = function1()
Or you could modify the contents of the list without changing the reference.
或者您可以在不更改引用的情况下修改列表的内容。
def function1(list_arg):
del list_arg[:] # Clears the array
'a = some array'
list_arg.extend(a)
回答by H?vard S
What I think you are asking is why after calling f(a), when fre-assigns the ayou passed, ais still the "old" ayou passed.
我认为您要问的是为什么在调用之后f(a),f重新分配a您通过的时,a仍然是a您通过的“旧” 。
The reason for this is how Python treats variables and pass them to functions. They are passed by reference, but the reference is passed by value(meaning that a copy is created). This means that the reference you have inside fis actually a copy of the reference you passed. This again implies that if you reassign the variable inside the function. It is a local variable existing only inside the function; re-assigning it won't change anything in outside scopes.
原因在于 Python 如何处理变量并将它们传递给函数。它们是通过引用传递的,但是引用是通过值传递的(意味着创建了一个副本)。这意味着您内部的引用f实际上是您传递的引用的副本。这再次意味着如果您在函数内部重新分配变量。它是一个只存在于函数内部的局部变量;重新分配它不会改变外部范围内的任何内容。
Now, if you rather than reassigning the local variable/reference inside f(which won't work, since it's a copy) perform mutable operations on it, such as append(), the list you pass will have changed after fis done.
现在,如果您不是在内部重新分配局部变量/引用f(这将不起作用,因为它是副本)对其执行可变操作,例如append(),您传递的列表将在f完成后发生变化。
See also the question How do I pass a variable by reference?which treats the problem and possible solutions in further detail.
另请参阅问题如何通过引用传递变量?它更详细地处理问题和可能的解决方案。
TL;DR:Reassigning a variable inside a function won't change the variable you passed as an argument outside the function. Performing mutable operations on the variable, however, will change it.
TL;DR:在函数内部重新分配变量不会更改您作为函数外部参数传递的变量。然而,对变量执行可变操作会改变它。

