인터넷에 뒤져보면 python의 reduce 함수에 대해서는 많이 있는데, 정확한 명세를 알려 주는 글은 잘 없는 것 같아서 직접 정리해 본다.
reduce(func, iterable , (optional)value)
from functools import reduce
# 케이스 1
test_list = [20, 5, 4, 3]
result = reduce(lambda a, b: a - b, test_list)
print(result)
# 결과: 8
# 케이스 2
test_list = [20, 5, 4, 3]
result = reduce(lambda a, b: a - b, test_list, 100)
print(result)
# 결과: 68
func:
reduce 과정이 진행되면서 실행될 함수로, 람다 함수든 일반 함수든 상관없지만, func(a,b) 형태로 파라미터 두 개를 받아야 한다.
a는 reduce를 진행하면서 누적된 값, b는 iterable 객체에서 가져온 원소이다.
당연히 파라미터 순서가 상관 있으니, 유의해야 한다. 대부분의 인터넷 예시에선 +를 사용하여 이 점이 잘 드러나지 않아서, 일부러 -를 사용해 보았다. 만약 파라미터 순서가 바뀐다면...
from functools import reduce
test_list = [20, 5, 4, 3]
# 케이스 1에서 a-b가 b-a로 바뀐 상태
result = reduce(lambda a, b: b - a, test_list)
print(result)
# 3 - (4 - (5-20))
# 출력 : -16
iterable
list, tuple, .. 등등 순회 가능한 요소는 모두 가능하다.
value
위 케이스 1,2의 차이가 초기값의 유무이다. 이 값이 주어지지 않았다면 iterable 객체의 첫번째 원소를 초기값으로 사용하여, reduce 과정에서 맨 처음에 첫번쨰 원소와 두번째 원소에 대해 fucn을 실행한다. 위의 케이스 1에선 20 -5 가 첫번째로 수행되었다.
초기값이 주어지면, 맨 처음에 value와 첫번쨰 원소에 대해 fucn를 실행한다. 위의 케이스 2에선 100 -20이 첫번째로 수행되었다.
즉, 초기값 유무에 따라 func 함수의 실행 횟수가 1번 차이가 난다. 아래의 예시를 보면 이해가 빠를 것이다.
from functools import reduce
test_list = [20, 5, 4, 3]
def reduce_fun(a, b):
print("함수 실행")
return a - b
result = reduce(reduce_fun, test_list)
print(result)
result = reduce(reduce_fun, test_list, 100)
print(result)
""" 출력:
함수 실행
함수 실행
함수 실행
8
함수 실행
함수 실행
함수 실행
함수 실행
68
"""
reduce 코드 살펴보기
_initial_missing = object()
def reduce(function, sequence, initial=_initial_missing):
it = iter(sequence)
if initial is _initial_missing:
try:
value = next(it)
except StopIteration:
raise TypeError("reduce() of empty sequence with no initial value") from None
else:
value = initial
for element in it:
value = function(value, element)
return value
functools.py에 정의된 reduce 함수의 내용이다. 내용은 크게 어렵지 않으니 천천히 살펴보자. initial 파라미터의 유무에 따라 value=initial 또는 value =next(it)를 통해 시작값을 정의한다. 시작값이 주어지지 않았다면 이미 본격적인 reducing 과정 전에 원소를 하나 순회하므로, 순회 횟수에 차이가 생기는 것이다. 아래엔 value = function(value, element)를 통해 값을 계속 갱신한다. 이 부분을 통해 왜 fucntion의 파라미터 순서가 상관 있는지, 꼭 파라미터 2개만 들어가야 하는지 알 수 있을 것이다.
'프로그래밍 > Python' 카테고리의 다른 글
Python 행정구역별 위도/경도 좌표 검색 라이브러리 - Korean-geocoding (2) | 2022.04.10 |
---|---|
AWS DynamoDB python에서 사용하기 (Boto3) (0) | 2021.07.13 |
pip 이용시 Requirements.txt를 조건에 따라 패키지 설치하도록 설정하기 (0) | 2021.03.25 |
Slacker를 활용하여 Slack 메세지를 보내는 봇을 만들고, 오류를 자동 전송하도록 하기 (0) | 2020.02.22 |
데이터 저장에 구글 스프레드시트와 API 활용하기 with Python (1) | 2020.02.20 |