13

Python 3.2 documentation機能composeを含むCollin Winter's functional moduleを指す:COMPOSE機能および機能モジュール

COMPOSE()関数は、関数合成を実現します。他の ワードでは、outerとinnerの呼び出し可能コードの周りにラッパーを返します。 のように、innerからの戻り値は直接outerに渡されます。

残念ながら、このモジュールは2006年7月から更新されていません。私は交換があるかどうか疑問に思います。

今のところ私はcomposeの機能が必要です。次の元のfunctional.composeの定義はまだPython 3に適していますか?

def compose(func_1, func_2, unpack=False): 
    """ 
    compose(func_1, func_2, unpack=False) -> function 

    The function returned by compose is a composition of func_1 and func_2. 
    That is, compose(func_1, func_2)(5) == func_1(func_2(5)) 
    """ 
    if not callable(func_1): 
     raise TypeError("First argument to compose must be callable") 
    if not callable(func_2): 
     raise TypeError("Second argument to compose must be callable") 

    if unpack: 
     def composition(*args, **kwargs): 
      return func_1(*func_2(*args, **kwargs)) 
    else: 
     def composition(*args, **kwargs): 
      return func_1(func_2(*args, **kwargs)) 
    return composition 

SO questionは多少関連しています。 Pythonがcomposeの特殊構文をサポートするかどうかを尋ねます。

+0

Pythonの3が 'callable'がキーワードに建てられているotのない - それは、通常は'に置き換えられますhasattr(obj、 "__call__") 'そうでなければ、上記のコードはうまくいくはずです。 – jsbueno

+3

3.2で 'callable()'が追加されました。 –

+0

私はそれがPython 3.2でうまくいくはずだと思います。他の人が指摘しているように、Python 3.0と3.1では 'callable'を実装する必要がありますが、3.2に満足すればコピー、ペースト、クレジットしてください。 –

答えて

6

composeの実装は、上記のコメントで説明したように、python 3.2に対して有効です。 あなたが与えたライブラリのほとんどの機能には、documentationで書かれたPythonの同等機能があります。

mapfilterなどの関数は、既にPythonで実装されており、単純にリスト内包表記としても表現できます。 Pythonはid関数を持っています(整数として)オブジェクトのアイデンティティを返すが、ライブラリのid関数はlambda x: xとして表すことができます。あなたは面白いかもしれません

別のモジュールがitertoolspartialreduceありfunctoolsある(foldlに似ていますが、引数の順序は同じではありません)。ここで

は、私は標準ライブラリで見つけられなかったことをそれらのいくつかの簡単な実装です:

from functools import reduce 

def flip(f): 
    if not callable(f): 
     raise TypeError("Cannot filp a non-callable object") 
    def result(*args, **kw): 
     args = list(args) 
     args.reverse() 
     return f(*args, **kw) 
    return result 

def ilast(i): 
    return reduce(lambda _, x: x, i) 

def iscanl(f, v, seq): 
    yield v 
    for a in seq: 
     v = f(v, a) 
     yield v 

def scanl(*args, **kw): 
    return list(iscanl(*args, **kw)) 

def foldl(*args, **kw): 
    return ilast(iscanl(*args, **kw)) 
# Or using reduce 
#def foldl(f, v, seq): 
# return reduce(f, seq, v) 

def iscanr_reverse(f, v, seq): 
    return iscanl(flip(f), v, seq) 

def scanr(*args, **kw): 
    result = list(iscanr_reverse(*args, **kw)) 
    result.reverse() 
    return result 

def foldr(*args, **kw): 
    return ilast(iscanr_reverse(*args, **kw)) 
関連する問題