是否可以在用户定义的第n个位置使用函数? Functool的partial函数可以处理对
的多个参数的部分求值from functools import partial
def f(x,y,z):
return [x,y,z]
然后
partial(f,1)(2,3)
[1,2,3]
和
partial(f,1,2)(3)
[1,2,3]
是否有可能在给定的论点位置咖喱?
curry_at(f,n)
如此
curry_at(f,2)(1,3)(2)
给予
[1,2,3]
在哪里,我想与可能的* arg和** kwarg保持一致,n
应该不大于常规参数的数量?
是否存在枚举参数以将前缀和后缀参数分隔到第n个插槽的方法?
答案 0 :(得分:1)
推荐这样的函数并不常见,但是在这种情况下,我认为最好是具有一些重复的静态定义,而不是依赖于复杂行为难以验证的动态函数-< / p>
def apply_at_1 (f, *a, **kw):
return lambda x, *a2, **kw2: \
f(x, *a, *a2, **kw, **kw2)
def apply_at_2 (f, *a, **kw):
return lambda x, y, *a2, **kw2: \
f(x, y, *a, *a2, **kw, **kw2)
def apply_at_3 (f, *a, **kw):
return lambda x, y, z, *a2, **kw2: \
f(x, y, z, *a, *a2, **kw, **kw2)
def dummy (a, b, c, d, *more):
print (a, b, c, d, *more)
apply_at_1(dummy, 2, 3, 4)(1, 5, 6, 7, 8)
# 1 2 3 4 5 6 7 8
apply_at_2(dummy, 3, 4, 5)(1, 2, 6, 7, 8)
# 1 2 3 4 5 6 7 8
apply_at_3(dummy, 4, 5, 6)(1, 2, 3, 7, 8)
# 1 2 3 4 5 6 7 8
当然,动态函数允许您在 any 位置应用参数,但是如果您需要在位置4(第五参数)应用参数,也许是时候考虑重构了。在这种情况下,我认为最好设定一个合理的限制,然后对自己进行约束。
由于键入的原因,其他功能语言也会执行类似的操作。考虑Haskell的liftA2
,liftA3
,liftA4
等。或者Elm的List.map
,List.map2
,List.map3
,List.map4
等。
有时候,KISS会更容易。
这是partial
版,支持通配符__
-
def __ ():
return None;
def partial (f, *a):
def combine (a, b):
if not a:
return b
elif a[0] is __:
return (b[0], *combine(a[1:], b[1:]))
else:
return (a[0], *combine(a[1:], b))
return lambda *b: f(*combine(a,b))
def dummy (a, b, c, d, *more):
print (a, b, c, d, *more)
partial(dummy, 1, __, __, 4)(2, 3, 5, 6, 7, 8)
# 1 2 3 4 5 6 7 8
partial(dummy, __, __, 3, __, __, 6, 7, 8)(1, 2, 4, 5)
# 1 2 3 4 5 6 7 8
答案 1 :(得分:0)
我尝试了使用索引和for循环的workarond,希望对您有所帮助:
from functools import partial
def curry_at(funtion,parameter,index,*args):
h = funtion
index-=1
ls = list(args)
ls.insert(index,parameter)
for arg in ls:
h = partial(h,arg)
return h()
a = curry_at(f,'a',2,'c','d')
b = curry_at(f,2,2,1,3)
a
['c','a','d']
b
[1,2,3]