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

Sli*_*Jim 13 python functional-programming

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

map ($ obj) [foo1,foo2]
Run Code Online (Sandbox Code Playgroud)

Python中使用lambda的示例:

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

它可以扩展到类函数吗?

也许来自运营商或itertools的东西?

lad*_*ini 13

你总是可以创建一个函数来为你处理它:

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])
Run Code Online (Sandbox Code Playgroud)

  • 唉,`break`是一个关键字,不能用作函数名. (4认同)
  • 应该是`reduce(lambda o,func:func(o),func_list,obj)`btw. (3认同)

jam*_*lak 10

我认为这应符合您的"功能"标准.为了回答您的问题,我认为没有一种干净的方式,您应该适应列表理解.

正如@JFSebastian所建议的那样

>>> from operator import methodcaller
>>> funcs = (lambda x: x + 1, lambda x: x + 2)
>>> obj = 5
>>> map(methodcaller('__call__', obj), funcs)
[6, 7]
Run Code Online (Sandbox Code Playgroud)

这是一种疯狂的方式:

>>> 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]
Run Code Online (Sandbox Code Playgroud)

正如@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]
Run Code Online (Sandbox Code Playgroud)

  • 为疯狂的库函数使用+1,以避免lambdas(然后在设置代码中抛出一些). (4认同)
  • @JFSebastian社区因为你的方式好多了而对它进行了嘲笑. (2认同)

Sli*_*Jim 7

问题是缺少的$运算符,它由一个简单的定义

def apply(f, a):
    return f(a)
Run Code Online (Sandbox Code Playgroud)

然后就可以($ obj)像这样在python中进行部分currying :partial(apply, a=obj)

有这个我们可以做一个地图申请

map(partial(apply, a=obj), [foo1, foo2]))
Run Code Online (Sandbox Code Playgroud)


Blc*_*ght 5

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

results = [f(obj) for f in funcList]
Run Code Online (Sandbox Code Playgroud)

如果您一次不需要整个结果列表,而只需要一次迭代一个项目,那么生成器表达式可能会更好:

genexp = (f(obj) for f in funcList)
for r in genexp:
    doSomething(r)
Run Code Online (Sandbox Code Playgroud)

如果您的函数是方法,而不是基本函数,则有两种方法:

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

obj = SomeClass()
funcList = [obj.foo1, obj.foo2]
results = [f() for f in funcList]
Run Code Online (Sandbox Code Playgroud)

或者使用未绑定的方法,它们只是常规函数,期望将它们定义的类的实例作为它们的第一个参数(通常命名为self):

funcList = [SomeClass.foo1, SomeClass.foo2]
obj = SomeClass()
results = [f(obj) for f in funcList]
Run Code Online (Sandbox Code Playgroud)

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

for f in funcList:
    f(obj)
Run Code Online (Sandbox Code Playgroud)