蟒蛇;修改函数内的列表

时间:2014-02-26 22:20:10

标签: python 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]

当这样做时,它不起作用。执行function1(list1)后,list1保持不变。那么,如何使function1使用与数组list1相同的元素(数字)返回a

4 个答案:

答案 0 :(得分:17)

如果您为变量list_arg指定了某些内容,那么它将从那时开始指向新值。 之前指向该分配(您的原始列表)的值将保持不变。

如果您为该列表的元素分配了一些内容,则会更改原始列表:

list_arg[:] = list(a)

这将使您的代码按照您的意愿运行。

但请记住,就地更改很难理解,可能会让下一位必须维护代码的开发人员感到困惑。

答案 1 :(得分:3)

您可以对列表进行操作以更改其值(例如,向其添加内容或设置其值),但只有在对传入对象的引用进行操作时,更改才会反映在函数外部:

def function1 (list_arg):
   list_arg.append(5)

如果您在执行此操作时遇到问题,请打印id s:

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

打印:

1 4348413856
2 4348413856
3 4348411984
['a', 'b', 'c']

也就是说,x已就地更改,但是分配给函数的局部变量list_argx没有影响,因为它只是为{{1}分配了一个不同的对象}}

答案 2 :(得分:1)

您正在更改对局部变量的引用。当你以这种方式传入list_arg时:

def function1 (list_arg):

list_arg是对基础列表对象的引用。当你这样做时:

   list_arg = list(a)

您正在更改list_arg在函数中的含义。由于函数在此之后退出,list_arg = list(a)无效。

如果你想真正改变对列表的引用,你必须将它分配给函数的结果。

def function1 ():
   'a = some array'
   return list(a)

list1 = [0] * 5
list1 = function1()

或者您可以修改列表的内容而不更改引用。

def function1(list_arg):
    del list_arg[:]  # Clears the array
    'a = some array'
    list_arg.extend(a)

答案 3 :(得分:1)

我认为你问的是为什么在致电f(a)后,当f重新分配你通过的a时,a仍然是“旧”{{}你通过了。

这样做的原因是Python如何处理变量并将它们传递给函数。它们通过引用传递 ,但引用按值传递 (意味着创建了一个副本)。这意味着a中的引用实际上是您传递的引用的副本。这再次意味着如果您在函数内部重新分配变量。它是仅存在于函数内部的局部变量;重新分配它不会改变外部范围内的任何内容。

现在,如果您不是在f内重新分配局部变量/引用(这将无效,因为它是副本)对它执行可变操作,例如f,列表为您append()完成后,pass将发生变化。

另请参阅问题How do I pass a variable by reference?,该问题将更详细地处理问题和可能的解决方案。

TL; DR:在函数内重新分配变量不会更改作为函数外部参数传递的变量。但是,对变量执行可变操作会改变它。