Python:如何使用函数“in place”更改值?

13

我希望实现一个函数,允许对其参数的值进行“原地”重新分配。

例如,一个函数将增加参数x并减少参数y。(这只是一个简单的例子,用于说明 - 动机是XY实际上是大型数据帧的单个元素;它们的表达式很难处理;而且此操作将经历多次迭代。)

def incdec(x,y,d):
    x += d
    y -= d

理想情况下,应该运行为:

X = 5; Y = 7; d = 2
incdec(X,Y,d)

现在发现值为X=7和Y=5。但当然事情不是那么简单 - 我想知道为什么?


1
在函数中,你不能重新绑定这样的变量。 - Martijn Pieters
根据您提供的示例,这是不可能的,因为函数无法重新绑定传递给它的变量。当然,您仍然可以更改传递给函数的任何对象中的引用,因此如果您更详细地描述实际用例,可能会找到解决方案。 - l4mpi
1
你尝试实现的内容至少有两种解决方法;我已经写了一个简短的代码片段作为答案:https://gist.github.com/miku/9497430 - miku
如果您真正拥有一个数据框或numpy数组,那么可以。但是,像您展示的变量一样,不行。如果您能够将问题更新为numpy格式,那会更有帮助。 - Phil Cooper
我知道这已经有一段时间了,但我重新打开了关于@PhilCooper的评论,并编辑了您的问题,试图强调您正在谈论数据框架。那里的行为可能与字符串不同,因为之前标记为重复的是关于字符串的。 - Andrew Barber
显示剩余2条评论
1个回答

4

为什么你的函数不能改变X和Y的最终值?

在Python中,当一个带有参数的函数被调用时, 参数的值的副本被存储在局部变量中。 实际上,当你写:

def incdec(x,y,d):
    x += d
    y -= d

唯一变化的是函数中的 x 和 y 参数。但在函数结束时,局部变量会丢失。为了获取所需的值,您应该记住函数执行的操作。为了在函数结束后记住这些值,您应该像这样重新赋值 x 和 y:

def incdec(x,y,d):
    x += d
    y -= d
    return (x,y)

# and then 

X = 5; Y = 7; d = 2
X,Y = incdec(X,Y,d)

这可以起作用是因为X和Y是int类型。另外,你也可以使用列表来直接访问要更改的变量。

def incdec(list_1,d):
    list_1[0] += d
    list_1[1] -= d
    #no return needed

# and then 
X = 5; Y = 7; d = 2
new_list = [X, Y]
incdec(new_list,d) #the list has changed but not X and Y

不要误会,即便是之前提到的传递的参数仍然是一个副本,但当你复制一个列表时,只有引用被复制了,但它们仍然指向同一个对象。以下是一个演示:

number = 5
list_a = [number] #we copy the value of number
print (list_a[0]) # output is 5
list_b = list_a # we copy all references os list_a into list_b
print(list_b[0]) # output is 5
list_a[0]=99
print(list_b[0]) # output is 99
print(number)    # output is 5

正如您所看到的,list_a[0]list_b[0]是同一个对象,但数字不同。这是因为我们复制了number的值而不是引用。我建议您使用第一种解决方案。希望这能帮助到您。


1
在字典的情况下,也不需要返回。它们在函数中通过引用传递(https://dev59.com/ImUp5IYBdhLWcg3wvpcM#15078615)。 - shaurya airi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接