首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >functools.partial与functools.reduce的相互作用

functools.partial与functools.reduce的相互作用
EN

Stack Overflow用户
提问于 2015-10-23 17:11:50
回答 2查看 430关注 0票数 2

我有一个函数,我正在尝试做一个部分版本,然后将这个部分函数应用到一个约简语句中。

部分函数本身起作用,因为我可以正常地用一组参数调用它,它将返回正确的答案。但是,如果在减缩下应用,它会中断。

例如;

代码语言:javascript
复制
import functools

test=[1,2,3,4]

def base_function(mult=10,a=0,b=0):
    return(mult*(a+b))

#control function, should act like partial base_function with mult=1
def test_function1(a=0,b=0):
    return(a+b)

#stupid partial function that has destroyed my friday afternoon
test_function2=functools.partial(base_function,mult=1)
print(test_function2.args) #returns ()
print(test_function2.keywords) #returns {'mult':1} 

print(test_function1(a=1,b=2)) #returns 3 as expected
print(test_function2(a=1,b=2)) #returns 3 as expected! horray!

#so the partial function itself works when called normally

print(functools.reduce(test_function1,test,-20)) #returns -10
print(functools.reduce(test_function2,test,-20)) #returns TypeError: base_function() got multiple values for argument 'mult'

作为一个额外的奖励,如果我改变代码,使多个正位参数和更新的部分函数如此;

代码语言:javascript
复制
def base_function(mult,a=0,b=0):
    return(mult*(a+b))


def test_function1(a=0,b=0):
    return(a+b)

test_function2=functools.partial(base_function,1)
print(test_function2.args)
print(test_function2.keywords)

血淋淋的东西和reduce语句完全一样。

有人能给我解释一下吗?对于这种类型的错误,我能找到的唯一答案似乎适用于在函数中调用某个东西作为关键字和普通参数的情况--据我所知,在这里还没有发生这种情况--如果是这样的话,部分函数在正常调用时不应该工作得很好。“解决办法”使一个位置论点是可行的,但我很想知道是什么导致了这一错误,因为显然,我一定是误解了一些关键的东西。

编辑:感谢那些回答了我的问题的海报--我现在明白了为什么会发生这种情况,为什么要重新排列论点,或者让它们的位置来解决问题,所以我把它标记为“解决了”。

然而,我想知道是否有一种“整洁”的方法--一个类似于部分的操作符,它不仅返回一个部分对象,如果参数被正确传递,该对象的作用就像期望的函数,但是实际上返回一个任意的期望函数,而不需要预先定义这个任意函数。例:

代码语言:javascript
复制
import functools

def base_function(mult=10,a=0,b=0):
    return(mult*(a+b))

def test_function1(a=0,b=0):
    return(a+b)

test_function2=partial_like_operator(base_function,mult=1)

print(test_function2==test_function1) #prints true
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-23 20:34:39

@horoy是对的。

另一种解释方法是:

在引擎盖下,对reduce的调用会产生错误,结果是调用如下所示:

代码语言:javascript
复制
test_function2(x, y, mult=1)

其中xyreduce函数的局部变量。

你可以试一试,很容易地看到这不是一个有效的调用。传递的第一个参数必须对应于mult,因为这是函数的第一个参数,但是mult被传递给另一个值,作为kw。

在调用起作用的部分函数的测试中,您将ab作为kwargs传递,从而绕过了这个问题。

结论是,在使用部分时,最好是将函数的最后参数绑定在一起,而不是第一个参数。

票数 1
EN

Stack Overflow用户

发布于 2015-10-23 18:30:28

这一切都是按参数排序的。在您的测试用例中,通过使用a=1, b=2和使用第一个参数的reduce()显式地绕过顺序,它确实失败了。

然而,如果你扭转了它,这似乎是可行的:

代码语言:javascript
复制
def base_function(a=0, b=0, mult=10):
    return mult * (a + b)

至少这对我有好处!

在您的情况下,以下内容也很可能失败:

代码语言:javascript
复制
print(test_function2(1, 2))

这是因为它试图设置两次mult .

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33307963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档