함수형 프로그래밍 모듈

함수형 프로그래밍 모듈 (Functional Programming Modules)

이 장에서 설명하는 모듈들은 함수형 프로그래밍 스타일을 지원하는 함수와 클래스, 그리고 호출 가능 객체에 대한 일반 연산을 제공합니다.

출처: Python documentation

본문

이 장은 Python 표준 라이브러리의 함수형 프로그래밍 관련 모듈들을 정리한 개요 장입니다. 이 장에 문서화된 모듈들은 다음과 같습니다.

  • itertools — 효율적인 루핑을 위한 이터레이터 생성 함수. Itertool Functions와 Itertools Recipes를 다룹니다. 순열, 조합, 무한 시퀀스, 결합, 체인 등 다양한 이터레이터 생성 함수를 제공합니다.
  • functools — 고차 함수와 호출 가능 객체에 대한 연산. partial 객체를 다룹니다. 함수에 부분 적용, 캐싱, 단일 디스패치 등의 고차 함수 기능을 제공합니다.
  • operator — 표준 연산자를 함수로. Mapping Operators to Functions와 In-place Operators를 다룹니다. +, -, *, 비교, 논리 연산 등을 함수 형태로 제공하여 sorted()keymap()의 함수 인자로 사용할 수 있습니다.

이 모듈들은 함께 함수형 프로그래밍 패턴을 Python에서 구현하는 기반이 됩니다. itertools는 무한·유한 이터레이터를 조합해 효율적이고 메모리 절약적인 데이터 처리를 가능하게 하고, functools는 함수 재사용(부분 적용, 메모이제이션, 일반 함수 디스패치)을 도우며, operator는 연산자를 일급 함수로 만들어 함수형 스타일 코드를 간결하게 작성하게 합니다.

함수형 프로그래밍 스타일은 부수 효과를 피하고 데이터 변환과 함수 합성을 강조합니다. itertoolschain(), map(), filter() 같은 도구와 functoolsreduce(), partial()을 조합하면 명령형 루프보다 선언적이고 재사용 가능한 코드를 작성할 수 있습니다.

각 모듈은 서로 보완적인 역할을 담당합니다. itertoolsproduct(), permutations(), combinations() 같은 조합 생성 함수와 count(), cycle(), repeat() 같은 무한 이터레이터, islice(), takewhile(), dropwhile() 같은 슬라이싱·필터링 함수를 제공합니다. 이 함수들은 모두 지연(lazy) 평가로 동작하여 메모리 사용을 최소화합니다.

functoolsreduce()로 누적 계산을, partial()로 함수의 일부 인자를 고정하여 재사용을 돕고, lru_cache()/cache()로 메모이제이션을, singledispatch()로 타입 기반 다형성을 구현합니다. operatoritemgetter(), attrgetter(), add(), lt() 같은 함수들을 제공하여 sorted()max()key 인자 등에서 람다 대신 사용할 수 있어 더 빠르고 명확합니다.

이 세 모듈은 Python에서 함수형 프로그래밍을 실용적으로 적용하는 핵심 도구 모음이며, 별다른 외부 의존성 없이 표준 라이브러리만으로 강력한 함수형 패턴을 구현하게 해 줍니다.

itertools.product()는 여러 이터러블의 데카르트 곱을, permutations()combinations()는 순열과 조합을 생성하여 반복·중첩 루프를 함수 호출로 단순화합니다. accumulate()는 누적 합계·곱셈 등 prefix 계산을, groupby()는 연속된 요소를 키로 그룹화합니다.

functools.reduce(func, iterable)은 이터러블의 요소를 왼쪽에서 오른쪽으로 이진 함수로 결합해 단일 값으로 축약하며, 초기값을 initial 인자로 지정할 수 있습니다. singledispatch는 별도의 디스패치 등록 없이 @MyFunc.register(int)처럼 타입별 구현을 덧붙여 확장성을 높입니다.

operator 모듈은 itemgetter(n)이 시퀀스·매핑의 특정 항목을 꺼내는 호출 가능 객체를, attrgetter('attr')가 객체의 속성을 꺼내는 함수를 만들어 sorted(rows, key=itemgetter(1))처럼 간결하게 사용합니다. methodcaller('name', args)는 지정 메서드를 호출하는 함수를 만듭니다.

이렇게 세 모듈을 함께 사용하면 루프와 조건문 대신 함수 합성과 지연 평가로 데이터 파이프라인을 구성하여, 코드 재사용성과 가독성, 메모리 효율을 모두 높일 수 있습니다.

또한 itertoolstee()는 단일 이터레이터를 여러 독립 이터레이터로 복제하고, zip_longest()는 가장 긴 이터러블까지 채워가며 짝을 지어, zip()만으로는 처리하기 어려운 길이가 다른 시퀀스들도 손쉽게 결합할 수 있습니다. 이들은 성능이 중요한 데이터 처리 루프에서 자주 함께 사용됩니다.

이 모듈들은 함수형 스타일을 쓰지 않는 코드에서도 유용한데, functools.partial로 설정 객체를 미리 부분 적용해 콜백에 전달하거나, operator.attrgetter로 정렬·분류 키를 람다 없이 지정할 수 있어, 함수형 프로그래밍 여부와 무관하게 실용적인 가치가 큽니다.

더 알아보기 (Learn more)