在Python中对对象应用函数列表

在Python中对对象应用函数列表,python,functional-programming,Python,Functional Programming,在Python中,有没有干净的方法可以在没有lambda或list理解的情况下对对象应用函数列表?就像Haskell表达式一样: map ($ obj) [foo1,foo2] Python中的lambda示例: response = map(lambda foo:foo(obj),[foo1,foo2]) #fooX:object->Bool 它可以扩展到类函数吗 也许是operator或itertools的一些东西?我认为列表理解是基于另一个列表构建一个列表的最佳方式。从列表中应用

在Python中,有没有干净的方法可以在没有lambda或list理解的情况下对对象应用函数列表?就像Haskell表达式一样:

map ($ obj) [foo1,foo2]
Python中的lambda示例:

response = map(lambda foo:foo(obj),[foo1,foo2]) #fooX:object->Bool
它可以扩展到类函数吗


也许是operator或itertools的一些东西?

我认为列表理解是基于另一个列表构建一个列表的最佳方式。从列表中应用常规函数非常简单:

results = [f(obj) for f in funcList]
如果不需要一次完整的结果列表,而只需要一次迭代一个项目,则生成器表达式可能更好:

genexp = (f(obj) for f in funcList)
for r in genexp:
    doSomething(r)
如果您的函数是方法,而不是基本函数,则有两种方法:

使用绑定方法,在这种情况下,进行函数调用时根本不需要提供对象:

obj = SomeClass()
funcList = [obj.foo1, obj.foo2]
results = [f() for f in funcList]
或者使用未绑定的方法,这些方法只是常规函数,它们期望类的实例作为它们的第一个参数(通常称为
self
):

当然,如果不需要捕获函数的结果,只需编写一个循环即可:

for f in funcList:
    f(obj)

您始终可以创建一个函数来为您处理它:

def map_funcs(obj, func_list):
    return [func(obj) for func in func_list]

    # I was under the impression that the OP wanted to compose the functions,
    # i.e. f3(f2(f1(f0(obj))), for which the line below is applicable:
    # return reduce(lambda o, func: func(o), func_list, obj)


map_funcs(it, [Buy, Use, Break, Fix])

我认为这应该符合你的“功能”标准,为了回答你的问题,我不认为有一个干净的方法,你应该适应列表理解

如@J.F.Sebastian所建议

>>> from operator import methodcaller
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> obj = 5
>>> list(map(methodcaller('__call__', obj), funcs))
[6, 7]
下面是一个疯狂的方法:

>>> from itertools import starmap, repeat
>>> from types import FunctionType
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> obj = 5
>>> list(starmap(FunctionType.__call__, zip(funcs, repeat(obj))))
[6, 7]
正如@AleksiTorhamo所建议的

>>> from itertools import repeat
>>> from types import FunctionType
>>> obj = 5
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> list(map(FunctionType.__call__, funcs, repeat(obj)))
[6, 7]

问题是缺少
$
运算符,该运算符由

def apply(f, a):
    return f(a)
然后可以使用python中的分部代码执行currying
($obj)
,如下所示:
partial(apply,a=obj)

有了这个,我们可以做一个地图应用

map(partial(apply, a=obj), [foo1, foo2]))
这是我的解决方案:

def plus(i):
返回i+i
def mult(一):
返回i*4
函数=[plus,mult]
结果=[]
对于[“a”、“b”、“c”、“d”]中的i:
对于函数中的j:
结果.附加(j(i))
结果
Out[16]:['aa','aaaa','bb','bbbb','cc','cccc','dd','dddd']

toolz
有一个
compose
函数可以完成这一功能

from toolz import compose
compose(foo1, foo2)(obj)


是否有理由避免列表理解,例如[foo,foo2]][f(obj)表示f?你想对函数的返回值做什么?我只是觉得它们有点难看,不知道是否有其他选择,代码目前是一个列表理解:)@SlimJim不,它不难看!这是非常好的python代码。@SlimJim:List Comprehension是从Haskell(一种纯函数式语言)那里借来的-map/filter的功能并不比List Comprehension强。@SlimJim:所以我认为总结是:没有
map
lambda
或List Comprehension,你就做不到你需要的事情。你可以选择你想要的任何一个,但没有任何“干净”的替代方案(有些人可能会反对函数样式为“非音速”)。唉,
break
是一个关键字,不能用作函数名。@Blckknght感谢上帝为区分大小写的对象名。此外,还有一个更重要的忍者编辑,可以真正做提问者想要做的事情。应该是
reduce(lambda o,func:func(o),func_list,obj)
btw。我不知道OP是否想要
f3(f2(f1(obj))
[f1(obj),f2(obj),f3(obj)]
。我不知道Haskell,因此也不知道Haskell的
map($obj)[foo1,foo2]
做了什么
map
直观上应该返回另一个元素列表(即
[f1(obj)、f2(obj)、f3(obj)]
),但是如果OP想要的是函数组合,那么注释的
reduce
代码就是它所追求的。@ladaghini如果你看python等价物,你就会知道它是
[f1(obj)、f2(obj)、f3(obj)]
+1用于疯狂的库函数使用,以避免lambdas(然后在设置代码中加入一些)。问题是:“有没有干净的方法?”。谁会认为上面的代码是干净的?@J.F.Sebastian我已经开始喜欢它了:)不,但事实上我很确定这是实现OP要求的唯一方法,我会在我的回答中注意到。这太可怕了。没有借口。即使您要使用
应用
。它充其量只属于,例如。顺便说一句,这不是唯一糟糕的方法:
map(methodcaller(“'uuuu call'uuuu',obj),func'u list)
@J.F.Sebastian社区对它进行了wikied,因为你的方法要好得多。此外,正如J.F.Sebastian上面提到的那样,Haskell中的
($x)
,可以使用Python中的库函数作为
操作符.methodcaller('uu','x)
,来实现,虽然它看起来确实没那么漂亮。因此,为可读性定义一个
apply
函数可能是一个更好的选择。我认为这并不能回答问题。在这个问题中,只有一个对象和一个函数列表,但这里有一个函数列表和一个对象列表
from toolz import compose
compose(foo1, foo2)(obj)