모던 프로그래밍 언어들은 '람다(lambda)' 함수라고 하는 기능을 제공한다. 람다는 익명 함수(Anonymous functions)를 의미하기도 한다. 람다를 이용하면 함수의 선언이 짧아지고, 함수 자체를 다른 함수의 인자로 넘길 수 있다는 유연함을 얻을 수 있다.
파이썬 람다
파이썬에서도 람다(lambda)가 지원된다. 파이썬의 람다는 다음과 같이 선언할 수 있다.
lambda 매개변수 : 표현식
예를 들어 두 개의 인자를 받아서 값을 더해주는 함수는 다음과 같이 선언할 수 있다.
def hap(a, b):
return a + b
print(hap(1, 2))
# 3
이 함수를 람다로 표현해서 다음과 같이 사용할 수 있다.
result = (lambda a, b : a + b)(1, 2)
print(result)
# 3
이렇게 생성된 람다 함수를 변수에 할당해서 사용할 수도 있다.
hap = lambda a, b : a + b
print(hap(1, 2))
# 3
lambda 키워드를 통해 람다식을 만들었고, 그것을 hap이라는 변수에 할당했다. 이후 hap() 이라는 함수를 호출하면 람다로 생성한 람다식이 실행된다. 흥미로운 점은 이렇게 생성한 람다 함수를 다른 함수의 인자로 넘길 수도 있다는 점이다.
def execute(func, a, b):
return func(a, b)
result = execute(lambda a, b : a + b, 11, 12)
print(result)
# 23
람다 함수를 인자로 받고, 추가로 두 개의 인자를 더 받아서 람다함수의 실행 결과를 리턴해주는 execute() 함수를 생각해볼 수 있다. 두 수를 더하는 람다 함수를 첫 번째 인자로 넘겨주고, 더하고 싶은 11과 12를 두번째, 세번째 인자로 넘겨주면 람다함수가 실행되어 23이라는 결과가 리턴된다.
람다는 map(), reduce(), filter() 같은 컬렉션 데이터에 사용할 수 있는 함수와 같이 쓸 때 더 유용하다.
람다 - map()
람다 함수는 map() 함수와 함께 사용할 수 있다.
map(함수, 시퀀스)
map() 함수는 함수와 리스트나 문자열 혹은 튜플 같은 시퀀스를 인자로 받는다. 리스트에 들어있는 엘리먼트들을 하나씩 순회하면서 첫 번째 인자로 받은 함수를 적용하고, 그 결과 값을 담아서 새로운 리스트로 리턴한다.
예를 들어보자.
numbers = [1, 3, 5, 7, 9]
new_numbers = list(map(lambda a : a + 1, numbers))
print(new_numbers)
# [2, 4, 6, 8, 10]
1부터 10까지 숫자 중 홀수만 엘리먼트로 담고 있는 리스트가 있다. 이 리스트의 모든 엘리먼트에 1을 더해 새로운 리스트로 만들었다.
물론 람다를 사용하지 않고 for 문을 이용해서 리스트의 각 엘리먼트를 돌면서 1을 더한 후 결과 리스트로 값을 가져와도 된다. 하지만 람다를 이용해서 코드가 좀 더 간결해졌다.
람다 - reduce()
람다 함수는 functiontools 패키지의 reduce() 함수와 함께 사용할 수 있다.
reduce(함수, 시퀀스)
reduce() 함수는 함수와 함께 문자열이나 리스트, 튜플 같은 시퀀스를 인자로 받는다. 시퀀스에 들어있는 엘리먼트 값들에 순차적으로 함수를 적용한다.
예를 들어보자.
from functools import reduce
numbers = [2, 4, 6, 8, 10]
result = reduce(lambda a, b:a + b, numbers)
print(result)
# 30
리스트의 엘리먼트들을 순회하면서 람다를 적용한다. 이 때, 람다는 두 개의 인자를 받는데 첫 번째 인자는 누적되는 값이며 두 번째 인자는 시퀀스에 들어있는 엘리먼트 값이다. 따라서 lambda a, b : a + b 는 시퀀스에 들어있는 엘리먼트들의 값을 모두 더하라는 의미다.
또 다른 예를 들어보자.
from functools import reduce
chars = 'abcdefg'
result = reduce(lambda a, b:b + a, chars)
print(result)
# gfedcba
문자열 시퀀스에 b + a를 적용했다. 이는 문자열 시퀀스의 각 문자들을 b로 대입하고, 지금까지 더해온 문자열을 a로 받아서 b + a를 실행한다. 즉, 문자열의 순서를 뒤집는 코드다.
람다 - filter()
람다 함수는 filter() 함수와 함께 사용할 수 있다.
filter(함수, 시퀀스)
filter() 함수는 시퀀스에 들어있는 엘리먼트에 람다 함수를 적용해서 결과에 포함시킬지 여부를 판단한다.
예를 들어보자.
numbers = filter(lambda a : a % 2 == 0, range(10))
print(list(numbers))
# [0, 2, 4, 6, 8]
필터함수는 인자가 하나인 람다 함수를 첫 번째 인자로 받는다. 두 번째 인자로는 range(10)을 받았다. 결국 0부터 9까지 숫자를 순회하면서 람다 함수를 적용한 후, 람다함수가 True로 평가되는 엘리먼트만 결과로 포함했다. 즉 짝수만 포함했다.
filter() 함수와 람다를 이용해서 리스트나 튜플에 존재하는 엘리먼트 중 특정 조건을 만족하는 엘리먼트들만 걸러(filter)낼 수 있는 것이다.
같은 동작을 하는 코드를 filter()와 람다를 사용하지 않고 구현한다면 조금 더 길게 구현해야한다.
numbers = []
for i in range(10):
if i % 2 == 0 :
numbers.append(i)
print(numbers)
# [0, 2, 4, 6, 8]
댓글