함수형 프로그래밍
함수형 프로그래밍은 프로그램을 함수 중심으로 구성하는 프로그래밍 방식이다.
객체지향 프로그래밍이 객체의 상태와 행동을 중심으로 프로그램을 구성한다면, 함수형 프로그래밍은 데이터를 함수에 넣고 그 결과를 받아 처리하는 흐름에 가깝다.
함수형 프로그래밍에서는 다음과 같은 생각이 중요하다.
데이터를 직접 바꾸기보다 새로운 결과를 만든다.
같은 입력에는 같은 출력을 내는 함수를 선호한다.
작은 함수를 조합해 프로그램을 만든다.
예를 들어 숫자 리스트가 있다고 하자.
numbers = [1, 2, 3, 4, 5]
이 숫자들을 모두 2배로 만들고 싶다면 반복문을 사용할 수 있다.
numbers = [1, 2, 3, 4, 5]
result = []
for n in numbers:
result.append(n * 2)
print(result)
출력은 다음과 같다.
[2, 4, 6, 8, 10]
함수형 프로그래밍에서는 이 작업을 “각 원소에 어떤 함수를 적용한다”라고 생각할 수 있다.
이때 사용할 수 있는 대표적인 함수가 map()이다.
순수 함수
함수형 프로그래밍에서 자주 나오는 개념이 순수 함수이다.
순수 함수는 같은 입력이 들어오면 항상 같은 출력을 반환하는 함수이다.
def add(a, b):
return a + b
위 함수는 add(2, 3)을 호출하면 언제나 5를 반환한다.
외부 상태를 바꾸지도 않는다.
print(add(2, 3))
print(add(2, 3))
print(add(2, 3))
출력은 항상 같다.
5
5
5
반대로 함수 밖의 값을 직접 바꾸는 함수는 순수 함수라고 보기 어렵다.
total = 0
def add_to_total(x):
global total
total += x
이 함수는 실행할 때마다 외부 변수 total을 바꾼다.
함수형 프로그래밍에서는 이런 방식보다, 기존 값을 직접 바꾸지 않고 새로운 값을 반환하는 방식을 선호한다.
def add_value(total, x):
return total + x
이렇게 하면 함수의 동작을 예측하기 쉽고, 테스트하기도 편하다.
map
map()은 여러 데이터에 같은 함수를 적용할 때 사용한다.
형태는 다음과 같다.
map(함수, 반복가능한데이터)
예를 들어 숫자 리스트의 모든 값을 2배로 만들고 싶다고 하자.
numbers = [1, 2, 3, 4, 5]
def double(x):
return x * 2
result = map(double, numbers)
print(list(result))
출력은 다음과 같다.
[2, 4, 6, 8, 10]
map(double, numbers)는 numbers 안의 각 원소에 double() 함수를 적용한다.
1에 double 적용
2에 double 적용
3에 double 적용
4에 double 적용
5에 double 적용
결과적으로 각 값이 2배가 된다.
Python의 map()은 바로 리스트를 반환하지 않고 map 객체를 반환한다.
그래서 결과를 눈으로 확인하려면 list()로 감싸는 경우가 많다.
result = list(map(double, numbers))
lambda와 map
간단한 함수는 따로 def로 만들지 않고 lambda로 작성할 수도 있다.
numbers = [1, 2, 3, 4, 5]
result = list(map(lambda x: x * 2, numbers))
print(result)
출력은 다음과 같다.
[2, 4, 6, 8, 10]
lambda x: x * 2는 x를 받아서 x에 2를 곱한 값을 반환하는 짧은 함수이다.
위 코드는 다음 코드와 같은 의미이다.
def double(x):
return x * 2
map()은 각 원소를 변환할 때 사용한다고 생각하면 된다.
map
각 원소를 다른 값으로 바꾼다.
filter
filter()는 여러 데이터 중 조건에 맞는 값만 골라낼 때 사용한다.
형태는 다음과 같다.
filter(조건함수, 반복가능한데이터)
예를 들어 숫자 리스트에서 짝수만 골라내고 싶다고 하자.
numbers = [1, 2, 3, 4, 5, 6]
def is_even(x):
return x % 2 == 0
result = filter(is_even, numbers)
print(list(result))
출력은 다음과 같다.
[2, 4, 6]
filter()는 각 원소를 조건 함수에 넣어본다.
조건 함수가 True를 반환하면 남기고, False를 반환하면 제외한다.
1은 짝수인가? False
2는 짝수인가? True
3은 짝수인가? False
4는 짝수인가? True
5는 짝수인가? False
6은 짝수인가? True
그래서 결과에는 2, 4, 6만 남는다.
lambda를 사용하면 더 짧게 쓸 수 있다.
numbers = [1, 2, 3, 4, 5, 6]
result = list(filter(lambda x: x % 2 == 0, numbers))
print(result)
출력은 다음과 같다.
[2, 4, 6]
filter()는 조건에 맞는 값만 남길 때 사용한다.
filter
조건에 맞는 원소만 골라낸다.
reduce
reduce()는 여러 값을 하나의 값으로 누적해서 줄일 때 사용한다.
Python에서 reduce()를 사용하려면 functools에서 가져와야 한다.
from functools import reduce
예를 들어 숫자 리스트의 모든 값을 더하고 싶다고 하자.
from functools import reduce
numbers = [1, 2, 3, 4, 5]
def add(a, b):
return a + b
result = reduce(add, numbers)
print(result)
출력은 다음과 같다.
15
reduce()는 앞에서부터 값을 하나씩 누적한다.
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
최종 결과는 하나의 값 15가 된다.
lambda를 사용하면 다음처럼 쓸 수 있다.
from functools import reduce
numbers = [1, 2, 3, 4, 5]
result = reduce(lambda a, b: a + b, numbers)
print(result)
출력은 다음과 같다.
15
곱셈도 가능하다.
from functools import reduce
numbers = [1, 2, 3, 4, 5]
result = reduce(lambda a, b: a * b, numbers)
print(result)
출력은 다음과 같다.
120
계산 과정은 다음과 같다.
1 * 2 = 2
2 * 3 = 6
6 * 4 = 24
24 * 5 = 120
reduce()는 여러 원소를 하나의 결과로 합칠 때 사용한다.
reduce
여러 값을 하나의 값으로 줄인다.
map, filter, reduce 비교
세 함수를 비교하면 다음과 같다.
| map | 각 원소를 변환한다 | 원소 개수가 보통 유지됨 |
| filter | 조건에 맞는 원소만 남긴다 | 원소 개수가 줄어들 수 있음 |
| reduce | 여러 원소를 하나로 누적한다 | 하나의 값이 됨 |
예를 들어 다음 리스트가 있다고 하자.
numbers = [1, 2, 3, 4, 5]
map()은 각 값을 바꾼다.
list(map(lambda x: x * 2, numbers))
결과는 다음과 같다.
[2, 4, 6, 8, 10]
filter()는 조건에 맞는 값만 남긴다.
list(filter(lambda x: x % 2 == 0, numbers))
결과는 다음과 같다.
[2, 4]
reduce()는 하나의 값으로 합친다.
from functools import reduce
reduce(lambda a, b: a + b, numbers)
결과는 다음과 같다.
15
짧게 정리하면 다음과 같다.
map
바꾼다.
filter
고른다.
reduce
합친다.
함께 사용하기
map, filter, reduce는 함께 사용할 수도 있다.
예를 들어 숫자 리스트에서 짝수만 골라낸 뒤, 그 값들을 제곱하고, 최종 합계를 구한다고 하자.
from functools import reduce
numbers = [1, 2, 3, 4, 5, 6]
evens = filter(lambda x: x % 2 == 0, numbers)
squares = map(lambda x: x ** 2, evens)
result = reduce(lambda a, b: a + b, squares)
print(result)
출력은 다음과 같다.
56
과정은 다음과 같다.
원본 데이터
[1, 2, 3, 4, 5, 6]
짝수만 필터링
[2, 4, 6]
각 값을 제곱
[4, 16, 36]
모두 더하기
56
한 줄로도 쓸 수 있다.
from functools import reduce
numbers = [1, 2, 3, 4, 5, 6]
result = reduce(
lambda a, b: a + b,
map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers))
)
print(result)
다만 너무 한 줄로 길게 쓰면 읽기 어려울 수 있다.
함수형 프로그래밍이 항상 짧게 쓰는 것을 의미하지는 않는다.
읽기 좋은 코드가 더 중요하다.
리스트 컴프리헨션과 비교
Python에서는 map()과 filter() 대신 리스트 컴프리헨션을 자주 사용하기도 한다.
map() 예시는 다음과 같다.
numbers = [1, 2, 3, 4, 5]
result = list(map(lambda x: x * 2, numbers))
리스트 컴프리헨션으로는 다음처럼 쓸 수 있다.
numbers = [1, 2, 3, 4, 5]
result = [x * 2 for x in numbers]
결과는 같다.
[2, 4, 6, 8, 10]
filter() 예시는 다음과 같다.
numbers = [1, 2, 3, 4, 5, 6]
result = list(filter(lambda x: x % 2 == 0, numbers))
리스트 컴프리헨션으로는 다음처럼 쓸 수 있다.
numbers = [1, 2, 3, 4, 5, 6]
result = [x for x in numbers if x % 2 == 0]
결과는 같다.
[2, 4, 6]
Python에서는 간단한 변환이나 필터링은 리스트 컴프리헨션이 더 읽기 쉬운 경우가 많다.
그래도 map, filter, reduce는 함수형 프로그래밍의 핵심 흐름을 이해하는 데 중요하다.
함수형 프로그래밍의 장점
함수형 프로그래밍의 장점은 코드의 흐름을 데이터 변환 과정으로 이해하기 쉽다는 점이다.
데이터를 넣는다.
함수를 적용한다.
새로운 결과를 얻는다.
또한 순수 함수를 사용하면 같은 입력에 같은 출력이 나오므로 테스트하기 쉽다.
외부 상태를 직접 바꾸는 코드가 줄어들면 예상하지 못한 부작용도 줄일 수 있다.
예측하기 쉬운 코드
테스트하기 쉬운 함수
데이터 변환 흐름이 명확함
부작용 감소
함수형 프로그래밍의 주의점
함수형 프로그래밍 스타일을 지나치게 사용하면 코드가 오히려 읽기 어려워질 수 있다.
특히 lambda, map, filter, reduce를 여러 겹 중첩하면 처음 보는 사람이 이해하기 어렵다.
result = reduce(lambda a, b: a + b, map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers)))
이런 코드는 동작은 하지만 가독성이 좋지 않을 수 있다.
이럴 때는 중간 변수를 사용해 나누어 쓰는 편이 낫다.
evens = filter(lambda x: x % 2 == 0, numbers)
squares = map(lambda x: x ** 2, evens)
result = reduce(lambda a, b: a + b, squares)
함수형 프로그래밍은 코드를 짧게 쓰기 위한 기술이 아니다.
데이터를 안전하고 예측 가능하게 처리하기 위한 사고방식에 가깝다.
정리
함수형 프로그래밍은 프로그램을 함수 중심으로 구성하는 방식이다.
데이터를 직접 바꾸기보다 함수를 적용해 새로운 결과를 만드는 방식을 선호한다.
순수 함수는 같은 입력에 대해 항상 같은 출력을 반환하고, 외부 상태를 직접 바꾸지 않는 함수이다.
map()은 반복 가능한 데이터의 각 원소에 함수를 적용해 새로운 값으로 변환한다.
filter()는 조건에 맞는 원소만 골라낸다.
reduce()는 여러 원소를 하나의 값으로 누적해서 줄인다.
map
각 원소를 변환한다.
filter
조건에 맞는 원소만 남긴다.
reduce
여러 원소를 하나의 값으로 합친다.
Python에서는 map()과 filter() 대신 리스트 컴프리헨션을 사용하는 경우도 많다.
하지만 map, filter, reduce를 이해하면 함수형 프로그래밍의 기본 흐름을 이해할 수 있다.
함수형 프로그래밍의 핵심은 데이터를 함수에 통과시키며 변환하고, 가능한 한 부작용이 적은 코드를 작성하는 것이다.
map
바꾸기
filter
고르기
reduce
하나로 합치기
'STUDY' 카테고리의 다른 글
| [C언어] 포인터와 메모리 관리 개념 정리 (0) | 2026.05.29 |
|---|---|
| [자료구조] 스택, 큐, 링크드 리스트 구현 개념 정리 (0) | 2026.05.29 |
| [프로그래밍 기초] 정적 타이핑, 동적 타이핑, 강타입, 약타입 정리 (0) | 2026.05.29 |
| [컴퓨터 기초] 컴파일러와 인터프리터 차이 정리 (0) | 2026.05.29 |
| [객체지향] 객체지향 4대 특성 정리: 캡슐화, 상속, 다형성, 추상화 (0) | 2026.05.29 |