늒네 기록

[python] lambda와 reduce의 활용을 통한 리스트 아이템의 곱 구하기 본문

언어 공부 기록/python

[python] lambda와 reduce의 활용을 통한 리스트 아이템의 곱 구하기

jaeha lee 2020. 10. 1. 17:48

숫자로 이루어진 리스트 x가 있을때, x에 있는 모든 숫자의 합은 sum(x)로 쉽게 구할 수 있다. 그렇다면 x에 있는 모든 숫자의 곱을 구하는 함수는 바로 없을까?

 

이런 생각을 하고 구글링을 해보다가 처음 lambda, reduce함수를 활용하는 방법을 알게 된 분들이 많을 거라고 생각한다. 처음 검색을 하다 보면 이런 코드를 맞닥뜨리게 된다.

1
2
3
from functools import reduce
= [1357]
print(reduce(lambda x, y: x*y, l))
cs

매우 짧은 코드로, 출력된 결과를 보면 105로 원하는 답이 나왔다는 걸 알 수 있다. 그런데 도대체 여기서 무슨 일이 일어난 걸까? 이를 알기 위해서는 파이썬의 lambda와 reduce에 대해서 각각 이해할 필요가 있다.

 

lambda식은 이름을 붙여주지 않는, 런타임에 빠르게 만들어서 쓰고 버릴 함수라고 보면 된다. 람다식은 다음의 구조로 이루어져 있다.

 

- lambda x, y: x*y

맨 앞의 lambda는 람다식이 시작한다는 걸 알려준다.

- lambda x, y: x*y

그리고, ':'가 나오기 전까지 나오는 것들은 계산에 사용할 인자들이다.

- lambda x, y: x*y

마지막에 나오는 계산식, 혹은 expression은 리턴할 값이다.

 

사실상, 람다식은 아래의 lambda_to_func함수와 같은 역할을 한다.

1
2
3
4
5
6
7
8
9
from functools import reduce
 
= [1357]
 
def lambda_to_func(x,y):
    return x*y
 
print(reduce(lambda x, y: x*y, l))
print(reduce(lambda_to_func, l))
cs

reduce에 함수를 변수로 넣어줄 때는 함수 그 자체를 넣어주면 되므로 위와 같이 코드를 짜고 계산을 하면 둘 다 105로 같은 결과가 나오는 것을 확인할 수 있다.

 

lambda함수는 리턴할 expression만 직접 넣어줄 수 있으므로, 중간에 여러 줄로 되어있는 statement들(res = x*y 라든지)을 사용할 수 없다.

 

그리고 reduce는, 파이썬 공식 문서에 따르면 러프하는 아래의 함수와 같은 역할을 한다고 써있다.

1
2
3
4
5
6
7
8
9
def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value
cs

- 위의 구조에서 function은 누적된 계산값(value)와 새로 계산할 아이템(element)의 두 변수를 받게 되어있고,

- iterable에 있는 아이템을 순차적으로 받아 function에 넣어 계산하며,

- initializer 값을 넣어주면 최초의 value값을 이 initializer값을 쓰고, 아니면 iterable의 첫 아이템을 쓴다.

 

이 두 정보를 조합하면, reduce(lambda x, y: x*y, l) 함수는 l 안에 있는 첫 번째 아이템부터 마지막 아이템까지 순차적으로 곱한 값을 리턴하는 것을 알 수 있다.

반응형
Comments