2013-12-18 19 views
0

我編寫了一個代碼來獲取n個功能並將它們組合在一起。如果函數沒有收到任何輸入,它將返回我們稱之爲lambda函數的「x」(例如compose()(3)#將返回3) 這是我的代碼,我簡直不能看到問題:無法確定此功能組合代碼

def compose(*funcs): 
    if len(funcs)==0: 
     return lambda x: x 
    else: 
     for i in funcs[-1:0:-1]: 

      return lambda x: funcs[0](funcs[i](x)) 
+0

我是什麼?一個數字還是一個函數? –

+0

它的一個索引運行在從頭到尾的所有功能上。導致我想要做的是f1(f2(f3(...... fn(x))) – user2751595

+0

爲什麼你總是在第一次迭代之後從for循環返回? – Eric

回答

2

比方說,你有三個功能:

def f1(x): 
    return 'f1 %s' % x 

def f2(x): 
    return 'f2 %s' % x 

def f3(x): 
    return 'f3 %s' % x 

然後我們有一個函數撰寫:

def compose(*funcs): 
    def f(x): 
     ret = x 
     for func in funcs[::-1]: 
      ret = func(ret) 
     return ret 
    return f 

我們可以用這樣的:

F = compose(f1, f2, f3) 
print F('x') 

它會打印出:

f1 f2 f3 x 

希望這是你想要的。

0

我認爲你是在談論

def fn1(x): 
    return x+1 
def fn2(x): 
    return x**2 
def fn3(x): 
    return math.sin(x)**0.5 

def apply(my_list_of_stuff): 
    if len(my_list_of_stuff) == 1: 
     return my_list_of_stuff[0] 
    return my_list_of_stuff[0](apply(my_list_of_stuff[1:])) 

apply([fn1,fn2,fn3,7]) # -> fn1(fn2(fn3(7))) 

假設我理解你的要求

+0

組合是'combined_f = compose([fn1,fn2,fn3])''combined_f(7)' – Eric

0

功能組合可以使用reduce優雅地實現。您可以使用初始參數來實現你無輸入條件太:

import functools 

def compose(*funcs): 
    return functools.reduce(lambda f, g: lambda x: f(g(x)), funcs, lambda x: x) 
0

我認爲實現這個更好的辦法是:

def compose(*funcs): 
    chain = lambda f, g: lambda *a, **kw: f(g(*a, **kw)) 
    return reduce(chain, funcs, lambda x: x) 

將返回一個新的功能,那就是傳遞給它的函數列表的組成。如果你不關心kwargs,你可以這樣做:

def compose(*funcs): 
    chain = lambda f, g: lambda *a: f(g(*a)) 
    return reduce(chain, funcs, lambda x: x) 

例子:

>>> def compose(*funcs): 
...  chain = lambda f, g: lambda *a: f(g(*a)) 
...  return reduce(chain, funcs, lambda x: x) 
... 
>>> remove_newlines = compose(lambda l: "".join(l), lambda s: s.split("\n")) 
>>> remove_newlines("hello\n world") 
'hello world' 

注:python3,減少已移出STDLIB到functools,所以你需要做from functools import reduce

1

實現功能組合物的通常方法是這樣的:

def compose(*funcs): 
    def _inner(x): 
     functools.reduce(lambda acc, f: f(acc), funcs, x) 
    return _inner 

豪ver,爲了修復你的代碼,你可以這樣做:

def compose(*funcs): 
    if not funcs: # preferred to checking if len is 0 
     return lambda x: x 
    else: 
     return lambda x: funcs[0](compose(*funcs[1:])(x)) 
+0

很確定你不想要'反轉'那裏 – Eric

+0

@Eric固定的,我認爲它沒有倒轉工作,但後來意識到它的確如此。 – rlms

+0

@Eric Precisely – rlms