21. 람다 표현식(Lambda Expression)
1. 키워드
- 람다 표현식(Lambda Expression)
- 익명 함수(Anonymous Function)
2. 람다 표현식 사용하기
- 지금까지
def
로 함수를 정의해서 사용했는데, 이번에는 람다 표현식으로 익명 함수를 만드는 방법을 알아보자. - 람다 표현식은 식 형태로 되어 있다고 해서 람다 표현식이라고 부른다.
- 특히 람다 표현식은 함수를 간편하게 작성할 수 있어서 다른 함수의 인수로 넣을 때 주로 사용한다.
3. 람다 표현식으로 함수 만들기
- 람다 표현식을 사용하기 전에 먼저 숫자를 받은 뒤
10
을 더해서 반환하는 함수plus_ten
을 만들어보자.
return x + 10
으로 매개변수x
에10
을 더한 값을 반환하는 간단한 함수이다.
- 람다 표현식은 다음과 같이
lambda
에 매개변수를 지정하고:
(콜론) 뒤에 반환값으로 사용할 식을 지정한다.
- 실행을 해보면 함수 객체가 나오는데, 이 상태로는 함수를 호출할 수 없다.
- 왜냐하면 람다 표현식은 이름이 없는 함수를 만들기 때문이며, 람다 표현식을 익명 함수라고 부르기도 한다.
lambda
로 만든 익명 함수를 호출하려면 다음과 같이 람다 표현식을 변수에 할당해 주면 된다.
- 이제 람다 표현식을 살펴보면
lambda x: x + 10
은 매개변수x
하나를 받고,x
에10
을 더해서 반환한다는 뜻이다. - 즉, 매개변수, 연산자, 값 등을 조합한 식으로 반환값을 만드는 방식이다.
- 다음 그림과 같이
def
로 만든 함수와 비교해 보면 쉽게 알 수 있다.
1) 람다 표현식 자체를 호출하기
- 람다 표현식은 변수에 할당하지 않고 람다 표현식 자체를 바로 호출할 수 있다.
- 다음과 같이 람다 표현식을
()
(괄호)로 묶은 뒤에 다시()
를 붙이고 인수를 넣어서 호출하면 된다.
2) 람다 표현식 안에서는 변수를 만들 수 없다
- 람다 표현식에서 주의할 점은 람다 표현식 안에서는 새 변수를 만들 수 없다는 점이다.
- 따라서 반환값 부분은 변수없이 식 한 줄로 표현할 수 있어야 한다.
- 변수가 필요한 코드일 경우에는
def
로 함수를 작성하는 것이 좋다.
- 단, 다음과 같이 람다 표현식 바깥에 있는 변수는 사용할 수 있다.
3) 람다 표현식을 인수로 사용하기
- 함수의 인수 부분에서 간단하게 함수를 만들기 위해서 람다 표현식을 사용한다.
- 이런 방식으로 사용하는 대표적인 예가
map
이다. - 람다 표현식을 사용하기 전에 먼저
def
로 함수를 만들어서map
을 사용해 보자.
- 다음과 같이 숫자를 받은 뒤
10
을 더해서 반환하는 함수plus_ten
을 작성하고map
에plus_ten
함수와 리스트[1, 2, 3]
을 넣는다.
plus_ten
함수는 매개변수x
에10
을 더해서 반환하므로 리스트[1, 2, 3]
이[11, 12, 13]
으로 바뀌었다.- 지금까지
map
을 사용할 때map(str, [1, 2, 3])
과 같이 자료형int
,float
,str
등을 넣었는데, 사실plus_ten
처럼 함수를 직접 만들어서 넣어도 된다.
- 이제 람다 표현식으로 함수를 만들어서
map
에 넣어보자.
plus_ten
함수 대신 람다 표현식lambda x: x + 10
을 넣었다.- 이처럼 람다 표현식은 함수를 다른 함수의 인수로 넣을 때 매우 편리하다.
람다 표현식으로 매개변수가 없는 함수 만들기
- 람다 표현식으로 매개변수가 없는 함수를 만들 때는
lambda
뒤에 아무것도 지정하지 않고:
(콜론)을 붙인다. - 단, 콜론 뒤에는 반드시 반환할 값이 있어야 한다.
- 왜냐하면 표현식은 반드시 값으로 평가되어야 하기 때문이다.
4. 람다 표현식과 map
, filter
, reduce
함수 활용하기
- 이번에는 람다 표현식과
map
,filter
,reduce
함수를 함께 사용해 보자.
1) 람다 표현식에 조건부 표현식 사용하기
- 먼저 람다 표현식에서 조건부 표현식을 사용하는 방법을 알아보자.
- 다음은
map
을 사용하여 리스트a
에서3
의 배수를 문자열로 변환한다.
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(map(lambda x: str(x) if x % 3 == 0 else x, a))
[1, 2, '3', 4, 5, '6', 7, 8, '9', 10]
map
은 리스트의 요소를 각각 처리하므로lambda
의 반환값도 요소이어야 한다.- 여기서는 요소가
3
의 배수일 때는str(x)
로 요소를 문자열로 만들어서 반환했고,3
의 배수가 아닐 때는x
로 요소를 그대로 반환했다.
- 람다 표현식 안에서 조건부 표현식
if
,else
를 사용할 때는:
(콜론)을 붙이지 않는다. - 특히 람다 표현식에서
if
를 사용했다면 반드시else
를 사용해야 한다.
- 다음과 같이
if
만 사용하면 문법 에러가 발생하므로 주의해야 한다.
- 그리고 람다 표현식 안에서는
elif
를 사용할 수 없다. - 따라서 조건부 표현식은
식1 if 조건식1 else 식2 if 조건식2 else 식3
형식처럼if
를 연속으로 사용해야 한다.
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> 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
로 함수를 만들고if
,elif
,else
를 사용하는 것을 권장한다.
>>> def f(x):
... if x == 1:
... return str(x)
... elif x == 2:
... return float(x)
... else:
... return x + 10
...
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(map(f, a))
['1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20]
2) map
에 객체를 여러 개 놓기
map
은 리스트 등의 반복 가능한 객체를 여러 개 넣을 수도 있다.
- 다음은 두 리스트의 요소를 곱해서 새 리스트를 만든다.
>>> a = [1, 2, 3, 4, 5]
>>> b = [2, 4, 6, 8, 10]
>>> list(map(lambda x, y: x * y, a, b))
[2, 8, 18, 32, 50]
- 이렇게 리스트 두 개를 처리할 때는 람다 표현식에서
lambda x, y: x * y
처럼 매개변수를 두 개로 지정하면 된다. - 그리고
map
에 람다 표현식을 넣고 그다음에 리스트 두 개를 콤마로 구분해서 넣어준다. - 즉, 람다 표현식의 매개변수 개수에 맞게 반복 가능한 객체도 콤마로 구분해서 넣어주면 된다.
3) filter
사용하기
filter
는 반복 가능한 객체에서 특정 조건에 맞는 요소만 가져오는데,filter
에 지정한 함수의 반환값이True
일 때만 해당 요소를 가져온다.
- 먼저
def
로 함수를 만들어서filter
를 사용해 보자.
>>> def f(x):
... return x > 5 and x < 10
...
>>> a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
>>> list(filter(f, a))
[8, 7, 9]
- 리스트
a
에서8
,7
,9
를 가져왔다. - 즉,
filter
는x > 5 and x < 10
의 결과가 참인 요소만 가져오고 거짓인 요소는 버린다.
- 그럼 함수
f
를 람다 표현식으로 만들어서filter
에 넣어보자.
- 람다 표현식
lambda x: x > 5 and x < 10
을filter
에 넣어서5
보다 크면서10
보다 작은 수를 가져오도록 만들었다.
4) reduce
사용하기
reduce
는 반복 가능한 객체의 각 요소를 지정된 함수로 처리한 뒤 이전 결과와 누적해서 반환하는 함수이다.reduce
는 파이썬 3부터 내장 함수가 아니기 때문에functools
모듈에서reduce
함수를 가져와야 한다.
- 다음은 리스트에 저장된 요소를 순서대로 더한 뒤 누적된 결과를 반환한다.
>>> from functools import reduce
>>> def f(x, y):
... return x + y
...
>>> a = [1, 2, 3, 4, 5]
>>> reduce(f, a)
15
reduce
의 반환값이15
가 나왔다.- 함수
f
에서x + y
를 반환하도록 만들었으므로reduce
는 그림과 같이 요소 두 개를 계속 더하면서 결과를 누적한다.
- 이제 함수
f
를 람다 표현식으로 만들어서reduce
에 넣어보자.
lambda x, y: x + y
와 같이 매개변수x
,y
를 지정한 뒤x
와y
를 더한 결과를 반환하도록 만들었다.
map
, filter
, reduce
와 리스트 표현식
- 리스트(딕셔너리, 세트) 표현식으로 처리할 수 있는 경우에는
map
,filter
와 람다 표현식 대신 리스트 표현식을 사용하는 것이 좋다.
list(filter(lambda x: x > 5 and x < 10, a))
는 다음과 같이 리스트 표현식으로도 만들 수 있다.
- 리스트 표현식이 좀 더 알아보기 쉽고 속도도 더 빠르다.
- 또한,
for
,while
반복문으로 처리할 수 있는 경우에도reduce
대신for
,while
을 사용하는 것이 좋다. - 왜냐하면
reduce
는 코드가 조금만 복잡해져도 의미하는 바를 한 눈에 알아보기가 힘들기 때문이다. - 이러한 이유로 파이썬 3부터는
reduce
가 내장 함수에서 제외되었다.
reduce(lambda x, y: x + y, a)
는 다음과 같이for
반복문으로 표현할 수 있다.