🖇 람다 표현식이란?
🖇 람다 표현식을 인수로 사용하는 함수
🖇 람다 표현식 활용하기
처음 람다 표현식을 마주했을 때,
lambda 라는 낯선 키워드와 익숙하지 않은 문법에 당황했던 기억이 있다.
함수처럼 동작하는데 함수 이름이나 def도 없고, 한 줄로 끝나는 코드가 과연 무슨 일을 하는지 파악하기 어려웠다.
하지만 람다 표현식은 생각보다 자주 등장한다.
특히 데이터를 다루거나, map(), filter(), reduce(), sorted()와 같은 함수를 사용하면서 자주 쓰기 때문에 한 번 제대로 정리하고 넘어가는 것이 필요하다.
이 글에서는 람다 표현식의 정의 및 기본 구조부터, 자주 쓰이는 실전 예제까지 함께 정리해 보았다.
람다 표현식은 실제로 자주 사용되기 때문에 계속 보다 보면 금방 익숙해질 것이다.
람다 표현식을 들어가기 전에
함수에서 헷갈리기 쉬운 용어인 매개변수와 인자(인수)를 정리해 보자.
| 용어 | 뜻 | 언제 등장? | 예시 |
|---|---|---|---|
| Parameter(매개변수) | 함수를 정의할 때 괄호 안에 적는 변수 이름 | 함수 선언 시 | def greet(name): ← 여기서 name이 파라미터 |
| Argument(인자) | 함수를 호출할 때 실제로 넘기는 값 | 함수 호출 시 | greet('Alice') ← 여기서 Alice'가 아규먼트 |
매개변수(parameter)는 함수에 입력된 전달된 값을 받는 변수를 의미하고, 인자(argument)는 함수를 호출할 때 전달하는 입력값을 의미한다.
람다
: 람다(lambda)는 익명 함수(anonymous function)를 만들기 위한 키워드
: 이름이 없는 한 줄짜리 함수를 만들고 싶을 때 사용
람다 표현식(Lambda Expression)
: 익명 함수를 만들 때 사용하는 한 줄짜리 함수 표현 방식
람다 함수 (익명 함수)
: 람다 표현식으로 만드는 이름이 없는 짧은 함수
즉, 람다 표현식이란
매개변수, 연산자, 값 등을 조합한 식으로 반환값을 만드는 방식으로, 함수의 인수 부분에서 간단하게 함수를 만들 수 있어 효율적이다.
# 람다 표현식으로 함수 객체 생성 lambda 매개변수: 표현식 # 람다 표현식 자체를 함수로 호출 (lambda 매개변수: 표현식)(인수)
바로 와닿지 않을 수 있다.
아래에서 일반 함수와 람다 함수를 비교해서 살펴보자.
def add_two(x):
return x + 10
add_two(5) # [출력] 15
# 람다 표현식으로 함수 객체 생성
lambda x: x + 10
# [출력] <function <lambda> at 0x02C27270>
# 람다 표현식 자체를 함수로 호출
(lambda x : x + 10)(5)
# [출력] 15
이렇게 람다 표현식은 간단한 연산이나 일회성 함수를 작성할 때 유용하다.
그러나 복잡한 로직이나 재사용이 필요한 함수의 경우,
def를 사용하여 함수를 정의하는 것이 가독성과 유지보수 측면에서 더 좋다.
함수를 다른 함수의 인수로 넣는 매우 편리하고 간단한 방법은 람다 표현식을 사용하는 것이다.
람다 표현식은 간단하다는 특징 때문에 함수를 인수로 전달하는 코드를 쓸 때 조금 더 효율적으로 작성할 수 있다.
그래서 람다 함수는 다른 함수의 인수로 사용되는 경우가 많다.
람다 함수를 인수로 사용하는 대표적인 함수 3가지를 알아보자.
map()반복 가능한 객체의 모든 요소에 함수를 적용한다.
map(적용시킬 함수, 적용할 값들)
# 표현 방식
map(함수, 리스트 or 튜플)
# 예제) 구구단 2단 만들기
two = [i for i in range(10)]
# map() + 람다 함수
map(lambda x : x * 2, two)
# map을 list로 리턴하기
# list()로 감싸주지 않으면, map 객체가 출력되게 된다
list(map(lambda x : x * 2, two))
[출력]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
filter()조건에 맞는 요소만 필터링
즉, 지정한 함수의 반환값이 True일 때만 해당 요소를 반환 리스트에서 원하는 값들만 남길 수 있다.
filter(함수, 리스트)
# 예제) 0부터 9까지의 리스트에서 홀수인 요소만 남기기
two = [i for i in range(10)]
# map() + 람다 함수
list(filter(lambda x : x % 2 == 1, two))
[출력]
[1, 3, 5, 7, 9]
람다 함수를 사용하여 한 줄로 코드를 만들었는데
여기에서 코드를 더 줄일 수 있다!
파이썬은 자료형마다 참과 거짓이 있다.
0은 False 이고 0을 제외한 int 자료형은 True 인데,
위의 코드에서 생각해 보면
x % 2의 결과가 1일 때만 값을 남기기를 바라고, 1은True이다.파이썬은 다른 조건이 없으면 참일 때만 통과시키기 때문에
비교 연산자==가 없어도 출력이 그대로 될 것임을 예상할 수 있다!
list(filter(lambda x : x % 2, two))
[출력]
[1, 3, 5, 7, 9]
아주 흥미로운 인사이트를 얻었다 :)
reduce()각 요소를 지정된 함수로 처리한 뒤 이전 결과와 누적해서 반환
reduce()는 파이썬 3부터 내장 함수가 아니다. 따라서 functools 모듈에서 가져와야 한다.reduce(함수, 이터러블 객체)
# 예제) 예제: 리스트에 저장된 요소를 순서대로 더한 뒤 누적된 결과 반환하기
from functools import reduce
a = [1, 2, 3, 4, 5]
reduce(lambda x, y: x + y, a) # [출력] 15
여기까지 람다 표현식을 인수로 사용하는 대표적인 함수들을 알아봤다.
추가적으로
람다 표현식을 정렬 기준으로 사용하는 예제도 가져와봤다.
sorted()람다 표현식을 정렬 기준으로 사용할 수도 있다.
students = [('영희', 90), ('철수', 70), ('민수', 85)]
# 두 번째 값을 기준으로 정렬
sorted_students = sorted(students, key=lambda x: x[1])
sorted_students
[출력]
[('철수', 70), ('민수', 85), ('영희', 90)]
이렇게 하면 학생들의 점수를 기준으로 오름차순 정렬할 수 있다.
람다 표현식에서도 조건부 표현식을 사용할 수 있다.
간단한 조건이라면 람다 표현식을 활용해 효율적으로 코드를 작성할 수 있다.
람다 표현식에서 if를 사용했다면 반드시 else를 사용해야 한다.
elif는 사용할 수 없다.
-> 람다 표현식 내에서 조건부 표현식을 사용할 때 if만 단독으로 사용하면 SyntaxError가 발생한다.
위에서 다룬 map() 함수를 사용하여 3의 배수를 문자열로 반환하는 코드를 작성해 보자.
# 예제) 3의 배수를 문자열로 반환하기
a = list(range(1, 11))
list(map(lambda x: str(x) if x % 3 == 0 else x, a))
[출력]
[1, 2, '3', 4, 5, '6', 7, 8, '9', 10]
# 예제) 1은 문자열로 변환하고, 2는 실수로 변환, 3 이상은 10을 더하기
a = list(range(1, 11))
list(map(lambda x: str(x) if x == 1 else float(x) if x == 2 else x + 10, a))
[출력]
['1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20]
이렇게 조건이 복합해진다면,
억지로 람다 표현식을 사용하기 보다는 def로 함수로 구현하는 것 권장한다.
아래의 경우를 살펴보고 람다 표현식이 항상 정답은 아니라는 것도 생각해 볼 수 있다.
리스트(딕셔너리, 세트) 표현식으로 처리할 수 있는 경우
a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
# 람다 표현식
list(filter(lambda x: x > 5 and x < 10, a))
# 리스트 표현식
[i for i in a if i > 5 and i < 10] # [8, 7, 9]
[출력]
[8, 7, 9]
for, while 반복문으로 처리할 수 있는 경우
reduce는 코드가 조금만 복잡해져도 의미하는 바를 한 눈에 알아보기가 힘들다from functools import reduce
a = [1, 2, 3, 4, 5]
# 람다 표현식
reduce(lambda x, y: x + y, a)
# for 반복문
x = a[0]
for i in range(len(a) - 1):
x = x + a[i + 1]
x
[출력]
15
정해진 답이 있는 게 아니니 주어진 상황에서 효율적인 방식은 무엇일지 고민하는 자세가 중요할 것이다.