Composing functions in python

前端 未结 12 1163
北荒
北荒 2020-11-27 03:56

I have an array of functions and I\'m trying to produce one function which consists of the composition of the elements in my array. My approach is:

def compo         


        
相关标签:
12条回答
  • 2020-11-27 04:03

    pip install funcoperators is another library to implement it that allows infix notation:

    from funcoperators import compose
    
    # display = lambda x: hex(ord(list(x)))
    display = hex *compose* ord *compose* list
    
    # also works as a function
    display = compose(hex, ord, list)
    

    pip install funcoperators https://pypi.org/project/funcoperators/

    Disclaimer: I'm the creator of the module

    0 讨论(0)
  • 2020-11-27 04:04
    def compose (*functions):
        def inner(arg):
            for f in reversed(functions):
                arg = f(arg)
            return arg
        return inner
    

    Example:

    >>> def square (x):
            return x ** 2
    >>> def increment (x):
            return x + 1
    >>> def half (x):
            return x / 2
    
    >>> composed = compose(square, increment, half) # square(increment(half(x)))
    >>> composed(5) # square(increment(half(5))) = square(increment(2.5)) = square(3.5) = 12,25
    12.25
    
    0 讨论(0)
  • 2020-11-27 04:04

    More general solution of Imanol Luengo from my point of view (python notebook example):

    from functools import reduce
    from functools import partial
    
    def f(*argv, **kwargs):
      print('f: {} {}'.format(argv, kwargs))
      return argv, kwargs
    
    def g(*argv, **kwargs):
      print('g: {} {}'.format(argv, kwargs))
      return argv, kwargs
    
    def compose(fs, *argv, **kwargs):
      return reduce(lambda x, y: y(*x[0], **x[1]), fs, (argv, kwargs))
    
    h = partial(compose, [f, g])
    h('value', key='value')
    output:
    f: ('value',) {'key': 'value'}
    g: ('value',) {'key': 'value'}
    
    m = partial(compose, [h, f, g])
    m('value', key='value')
    output:
    f: ('value',) {'key': 'value'}
    g: ('value',) {'key': 'value'}
    f: ('value',) {'key': 'value'}
    g: ('value',) {'key': 'value'}
    
    0 讨论(0)
  • 2020-11-27 04:05

    You can also create an array of functions and use reduce:

    def f1(x): return x+1
    def f2(x): return x+2
    def f3(x): return x+3
    
    x = 5
    
    # Will print f3(f2(f1(x)))
    print reduce(lambda acc, x: x(acc), [f1, f2, f3], x)
    
    # As a function:
    def compose(*funcs):
        return lambda x: reduce(lambda acc, f: f(acc), funcs, x)
    
    f = compose(f1, f2, f3)
    
    0 讨论(0)
  • 2020-11-27 04:06

    This is my version

    def compose(*fargs):
        def inner(arg):
            if not arg:
                raise ValueError("Invalid argument")
            if not all([callable(f) for f in fargs]):
                raise TypeError("Function is not callable")
            return reduce(lambda arg, func: func(arg), fargs, arg)
        return inner
    

    An example of how it's used

    def calcMean(iterable):
        return sum(iterable) / len(iterable)
    
    
    def formatMean(mean):
        return round(float(mean), 2)
    
    
    def adder(val, value):
        return val + value
    
    
    def isEven(val):
        return val % 2 == 0
    
    if __name__ == '__main__':
        # Ex1
    
        rand_range = [random.randint(0, 10000) for x in range(0, 10000)]
    
        isRandIntEven = compose(calcMean, formatMean,
                                partial(adder, value=0), math.floor.__call__, isEven)
    
        print(isRandIntEven(rand_range))
    
    0 讨论(0)
  • 2020-11-27 04:07

    The easiest approach would be first to write a composition of 2 functions:

    def compose2(f, g):
        return lambda *a, **kw: f(g(*a, **kw))
    

    And then use reduce to compose more functions:

    def compose(*fs):
        return reduce(compose2, fs)
    

    Or you can use some library, which already contains compose function.

    0 讨论(0)
提交回复
热议问题