reduce

>>> functools.reduce(function, iterable[, initializer])

 

iterable 한 data를 왼쪽에서 오른쪽으로 누적적으로 fuction 의 인자로 넣어 하나의 결과를 반환하는 함수

python2 에서는 builtin 함수로 바로 사용할 수 있었지만 python3 에서는 functools 모듈의 함수로 포함되어 있다. 

 

[Link : iterable 과 iterator, 그리고 반복문]

functools.reduce(function, iterable[, initializer])
Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned.

 

[Python3 기준 예제]

>>> from functools import reduce
>>> data = [1, 2, 3, 4, 5]
>>> def sum(a, b):
...     return a + b
...
>>> reduce(sum, data)            
15 

 

위의 reduce 를 풀어 써보면 다음과 같다.

 

sum(sum(sum(sum(1, 2), 3), 4), 5)

==> ((((1 + 2) + 3) + 4) +5)

==> 15

 

 

functools.reduce 에 정의된 바와 같이 two arguments 에 대해 동작하고, 만약 인자가 3개인 function 을 넣을 경우 아래와 같이 Exception 이 발생한다. 

 

data = [1, 2, 3, 4, 5]
>>> def sum(a, b, c):
...     return a + b + c
... 
>>> reduce(sum, data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sum() missing 1 required positional argument: 'c'

 

 

가장 흔하게 쓰이는 factorial 계산을 위해 reduce를 아래와 같이 사용할 수도 있다. 

 

[Case 1]

import functools 

def mult(x, y):
    return x * y


def factorial(n):
    if n == 0:
        return 1
    else:
        functools.reduce(mult(n,factorial(n - 1)))

 

[Case 2]

>>> import functools, operator
>>> functools.reduce(operator.mul, xrange(1, 6))
120

 


>>> help(reduce)
Help on built-in function reduce in module _functools:                                                                                                                                                      

reduce(...)
    reduce(function, sequence[, initial]) -> value

    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.

 

 

참고 문헌

https://stackoverflow.com/questions/26152469/using-reduce-function-in-python-to-find-factorial