람다(Lambda)

반응형

3.5. 람다(Lambda)

오늘은 람다 형식과 그것을 이용하는 여러가지 함수들에 대해서 알아보겠습니다. 당장 완벽하게 소화하실 필요는 없을 것 같구요, 가벼운 마음으로 이런 것이 있다는 정도만 아셔도 되지 않을까 합니다. 람다 형식은 인공지능 분야나 AutoCAD라는 설계 프로그램에서 쓰이는 Lisp 언어에서 물려받았다고 하는데요, 함수를 딱 한 줄만으로 만들게 해주는 훌륭한 녀석입니다. 사용할 때는 아래와 같이 써주면 되지요.

lambda 인자 : 표현식

다음은 두 수를 더하는 함수입니다.

>>> def hap(x, y):
...   return x + y
...
>>> hap(10, 20)
30

이것을 람다 형식으로는 어떻게 표현할까요?

>>> (lambda x,y: x + y)(10, 20)
30

너무나 간단하죠? 함수가 이름조차도 없습니다. '그냥 10 + 20이라고 하면 되지'라고 말씀하시면 미워잉~.

몇 가지 함수를 더 배워보면서 람다가 어떻게 이용되는지 알아보도록 하죠.

map()

먼저 map 함수를 볼까요?

map(함수, 리스트)

이 함수는 함수와 리스트를 인자로 받습니다. 그렇죠? 그리고, 리스트로부터 원소를 하나씩 꺼내서 함수를 적용시킨 다음, 그 결과를 새로운 리스트에 담아준답니다. 말이 좀 복잡하죠? 그럴 때 예제를 보는 게 최고죠.

>>> map(lambda x: x ** 2, range(5))             # 파이썬 2
[0, 1, 4, 9, 16]  
>>> list(map(lambda x: x ** 2, range(5)))     # 파이썬 2 및 파이썬 3
[0, 1, 4, 9, 16]

위의 map 함수가 인자로 받은 함수는 lambda x: x ** 2구요, 리스트로는 range(5)를 받았습니다. range 함수는 알고계시죠? range(5) 라고 써주면 [0, 1, 2, 3, 4]라는 리스트를 돌려줍니다. 그리고 x ** 2 라는 것은 x 값을 제곱하라는 연산자죠.

map 함수는 리스트에서 원소를 하나씩 꺼내서 함수를 적용시킨 결과를 새로운 리스트에 담아주니까, 위의 예제는 0을 제곱하고, 1을 제곱하고, 2, 3, 4를 제곱한 것을 새로운 리스트에 넣어주는 것입니다.

위의 예제를 람다가 아닌 보통의 함수로 구현하면 어떻게 될까요?

reduce()

이번엔 reduce 함수를 살펴봅시다.

reduce(함수, 순서형 자료)

형식은 위와 같구요, 순서형 자료(문자열, 리스트, 튜플)의 원소들을 누적적으로(?) 함수에 적용시킨답니다. 말이 진짜 어렵군요. 예제를 살펴보도록 하겠습니다.

>>> from functools import reduce   # 파이썬 3에서는 써주셔야 해요  
>>> reduce(lambda x, y: x + y, [0, 1, 2, 3, 4])
10

위의 예제는 먼저 0과 1을 더하고, 그 결과에 2를 더하고, 거기다가 3을 더하고, 또 4를 더한 값을 돌려줍니다. 한 마디로 전부 다 더하라는 겁니다. 생각보다 쉽죠?

하… 하… 하…

의기양양하게 '예'라고 대답하신 분들을 위해 짜증나는 예제를 권해드리죠~.

>>> reduce(lambda x, y: y + x, 'abcde')
'edcba'

전 원래 뭐 하나를 배우면 꼭 엽기적인 실험을 해본답니다. 더 짜증나라고 설명 안 해드릴랍니다~

filter()

그 다음은 filter를 살펴볼 차례입니다. 필터가 뭐죠? 정수기에서 물을 걸러주는 것이 필터죠? 에어컨의 바람 들어가는 곳에도 필터가 달려있구요.

filter(함수, 리스트)

파이썬의 필터는 이렇게 생겼는데요, 리스트에 들어있는 원소들을 함수에 적용시켜서 결과가 참인 값들로 새로운 리스트를 만들어줍니다. 다음은 0부터 9까지의 리스트 중에서 5보다 작은 것만 돌려주는 예제입니다.

>>> filter(lambda x: x < 5, range(10))       # 파이썬 2
[0, 1, 2, 3, 4]  
>>> list(filter(lambda x: x < 5, range(10))) # 파이썬 2 및 파이썬 3
[0, 1, 2, 3, 4]

lambda x: x<5 라고 쓰니까 왠지 수학책에서 본 듯한 느낌이 들지 않습니까? 수학자들이 파이썬을 좋아한다던데…

위의 예제가 어떻게 돌아가는지는 척 보면 아시겠죠?

0부터 9까지의 리스트에서 숫자를 하나씩 꺼냅니다.

그 숫자를 x라 하고, x < 5 가 '참'이면 살려줍니다.

살아남은 것들은 새로운 리스트에 넣어줍니다. 끝.

자, 이번엔 홀수만 돌려주는 filter를 만들어 보도록 합시다.

먼저 홀수가 뭔지 생각해볼까요?

짝수는 2로 나누어 떨어지는 수이고, 홀수는 2로 나누어 떨어지지 않는 수입니다.

짝수를 2로 나눈 나머지는 0이고, 홀수를 2로 나누면 나머지가 1이죠.

또, 나머지를 구할 땐 %라는 연산자를 쓰면 됩니다. 예를 들어서, 50을 8로 나누면 몫은 6이고 나머지는 2니까 50%8은 2가 되는 거지요.

이제 홀수를 돌려주는 필터를 만들어 보겠습니다.

>>> filter(lambda x: x % 2, range(10))        # 파이썬 2
[1, 3, 5, 7, 9]  
>>> list(filter(lambda x: x % 2, range(10)))  # 파이썬 2 및 파이썬 3
[1, 3, 5, 7, 9]
지난 시간에 '참'은 1이고 '거짓'은 0이라고 했죠? 위의 filter 함수를 실행시키면,
0을 2로 나눈 나머지는 0이니까 람다 함수의 결과값은 0이고, 0은 '거짓'이니까 버려집니다.
1을 2로 나눈 나머지는 1이니까 람다 함수의 결과값은 1이고, 1은 '참'이니까 통과하지요.
이런 식으로 수행하면서 홀수만 돌려주게 되는 거지요.