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

时间:2012-07-31 08:51:07

标签: python functional-programming

在没有lambda或list comprehensions的情况下,是否有任何干净的方法在Python中的对象上应用函数列表?像Haskell表达式一样:

map ($ obj) [foo1,foo2]

Python中的lambda示例:

response = map(lambda foo:foo(obj),[foo1,foo2]) #fooX:object->Bool

它可以扩展到类函数吗?

也许是来自operator或itertools的东西?

6 个答案:

答案 0 :(得分:12)

您可以随时创建一个功能来为您处理:

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])

答案 1 :(得分:9)

我认为这应该适合您的功能性'标准,为了回答你的问题,我不认为有一种干净的方式,你应该适应列表理解。

正如@ J.F.Sebastian所建议的

>>> from operator import methodcaller
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> obj = 5
>>> 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)
>>> map(FunctionType.__call__, funcs, repeat(obj))
[6, 7]

答案 2 :(得分:7)

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

简单定义
def apply(f, a):
    return f(a)

然后我可以像这样用python中的部分($ obj)进行调整:partial(apply, a=obj)

有了这个,我们可以用

来做地图
map(partial(apply, a=obj), [foo1, foo2]))

答案 3 :(得分:2)

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

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):

funcList = [SomeClass.foo1, SomeClass.foo2]
obj = SomeClass()
results = [f(obj) for f in funcList]

当然,如果您不需要捕获函数的结果,那么简单地编写一个循环是最简单的:

for f in funcList:
    f(obj)

答案 4 :(得分:0)

这是我的解决方案:

def plus(i):
    return i+i

def mult(i):
    return i*4

functions = [plus,mult]

result=[]

for i in ["a","b","c","d"]:
    for j in functions:
        result.append(j(i))

结果 Out [16]:['aa','aaaa','bb','bbbb','cc','cccc','dd','dddd']

答案 5 :(得分:0)

toolz库具有一个compose函数,即可执行此操作。

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