functools
functools.cmp_to_key
functools.cmp_to_key(func)는 sorted()와 같은 정렬 함수의 key 매개변수에 함수(func)를 전달할 때 사용하는 함수입니다. 단, func() 함수는 두 개의 인수를 입력해 첫 번째 인수를 기준으로 그 둘을 비교하고 작으면 음수, 같으면 0, 크면 양수를 반환하는 비교 함수이어야 합니다.
예시
2차원 평면 위의 점 N개를 (x, y) 좌표로 구성한 리스트가 있고 이 리스트를 y 좌표가 증가하는 순으로 정렬하되 y 좌표가 같으면 x좌표가 증가하는 순으로 정렬하를 프로그램입니다.
import functools
def xy_compare(n1: int, n2: int) -> int:
if n1[1] > n2[1]: # y좌표가 크면
return 1
elif n1[1] == n2[1]: # y좌표가 같으면
if n1[0] > n2[0]: # x좌표가 크면
return 1
elif n1[0] == n2[0]: # x좌표가 같으면
return 0
else: # x좌표가 작으면
return -1
else:
return 0 # x좌표가 작으면
src = [(0,4), (1, 2), (2, 1), (3, 4), (-1, 2)]
result = sorted(src, key=functools.cmp_to_key(xy_compare))
print(result) # [(0, 4), (1, 2), (2, 1), (3, 4), (-1, 2)]
xy_compare()와 같이 정렬에 사용하는 함수는 반드시 아래 3가지 중 하나를 반환해야 합니다.
- 양수
- 음수
- 0
functools.partial
functools.partial()은 하나 이상의 인수가 이미 채워진 새 버전의 함수를 만들 때 사용하는 함수입니다.
def add_mul(choice: str, *args: float) -> float:
if choice == "add":
result = 0
for arg in args:
result = result + arg
elif choice == "mul":
result = 1
for arg in args:
result = result * arg
return result
위의 함수는 입력한 인수의 합과 곱을 choice값에 따라 선택적으로 반환하는 사용자 정의 함수 add_mul()입니다.
만약 add_mul()함수를 활용해 add(), mul() 함수를 만들러면 아래처럼 작성할 수 있습니다.
def add(*args: float) -> float:
return add_mul("add", *args)
def mul(*args):
return add_mul("mul", *args)
print(add(1, 2, 3, 4)) # 10
print(mul(1, 2, 3, 4)) # 24
하지만, functools.partial()을 사용하면 아래처럼 더 간결하게 작성할 수 있습니다.
from functools import partial
add = partial(add_mul, "add")
mul = partial(add_mul, "mul")
print(add(1, 2, 3, 4)) # 10
print(mul(1, 2, 3, 4)) # 24
print(type(add)) # <class 'functools.partial'>
이처럼 partial은 하나 이상의 인수를 미리 채운 새로운 함수를 만드는데 유용합니다.
functools.reduce
functools.reduce(function, iterable)은 function을 반복 가능한 객체의 요소에 차례대로(왼쪽에서 오른쪽으로) 누적 적용하여 이 객체를 하나의 값으로 줄이는 함수입니다.
아래는 data의 요소를 모두 더해 반환하는 add()함수입니다.
from typing import Iterable
def add(data: Iterable[int]) -> int:
result = 0
for i in data:
result += i
return result
data = [1, 2, 3, 4]
result = add(data)
print(result) # 10
functools.reduce() 함수를 사용하면 아래처럼 코드를 수정할 수 있습니다.
import functools
data = [1, 2, 3, 4]
result = functools.reduce(lambda x, y: x + y, data)
print(result) # 10
이렇게 reduce() 함수를 사용하면 reduce()에 선언한 람다 함수를 data 요소에 차례대로 누적 적용하여 다음과 같이 계산합니다.
(((1+2)+3)+4)
참고로 람다 관련 글은 아래 링크를 확인해 보면 됩니다.
람다 관련 글
추가로 functools.reduce()를 활용해 최댓값도 구할 수 있습니다.
num_list = [3, 3, 9, 1, 4]
max_num = functools.reduce(lambda x, y: x if x > y else y, num_list)
print(max_num) # 9
'Python > Python' 카테고리의 다른 글
@property 데코레이터 (0) | 2023.07.01 |
---|---|
glob.glob() 함수 (0) | 2023.06.11 |
Python 라이브러리 - itertools (0) | 2023.05.20 |
Python 라이브러리 - operator.itemgetter (0) | 2023.05.18 |
Python 라이브러리 - statistics (0) | 2023.05.17 |