람다에 대해 내가 아는 것이라곤 그리스 문자 람다(λ)가 끝이다. 찾아보니 수학에 대한 람다도 있고, 우리가 알아봐야할 파이썬의 람다도 있었다. 아마도 수학에서 개념을 따온 것이 아닌가 생각해본다.
파이썬에서 람다는 런타임에 생성해서 사용할 수 있는 익명 함수이다. 그렇다! 이름도 없고 리터럴 방식이다.
리터럴 (literal)은 "값" 그 자체로, 고정된 값을 표현하는 것을 의미한다.
람다 함수는 필요한 수 만큼의 인자를 받지만 표현식이 하나 뿐이다. 표현 방법은 간단하다.
x = lambda a, b : a * b
print(x(5, 6))
>>> 30
람다가 가진 파워는 간단한 인라인 콜백함수를 만들거나 함수 안에서 간단한 처리를 할 때 나타난다.
콜백 함수란 어떤 이벤트가 발생했을 때 호출되는 함수이다.
콜백 함수하면 떠오르는 언어는 자바스크립트이지만, 파이썬 연습 중이므로 간단하게 파이썬으로 구현해봤다.
french_greeting = "bonjour"
def callback(greeting):
print(greeting)
def event(cb=None):
if cb != None:
cb()
event(callback(french_greetings))
>>> bonjour
위의 코드를 람다로 표현해보면
french_greeting = "bonjour"
def event(cb=None):
if cb != None:
cb()
event((lambda fg: print(fg))(french_greeting))
>>> bonjour
코드의 수가 줄어들어 깔끔해 보인다 🧼. 그리고 한 번만 쓰기 때문에 정의하지 않아도 되서 나중에 코드를 다시 볼 때 "얘는 뭐하는 애지?" 하지 않아도 된다 😂.
다음 코드를 실행해보고 print문으로 출력되는 출력결과를 확인해보고 types 모듈에 LambdaType 외에도 어떤 타입들이 있는지 조사해 보세요
import types
f = lambda x,y,z : x+y+z
print(f) # 1
print(type(f)) # 2
print(type(f) == types.LambdaType) # 3
# 출력 결과
<function <lambda> at 0x10d8fe4d0>
<class 'function'>
True
이럴 때 가장 먼저 찾아봐야할 곳이 바로 파이썬 공식 문서이다.
types 모듈은 파이썬 인터프리터를 구현하는데 많은 타입을 제공한다. 많은 타입들이 존재하지만 지금까지 배워왔던 문법의 타입을 위주로 정리해본다.
나머지는 공식 문서를 통해 확인하길 바란다 🤪.
다음과 같이 비밀번호의 길이와 대문자가 포함된 것을 확인하는 간단한 함수가 있다.
def check_password(password):
if len(password) < 8:
return 'SHORT_PASSWORD'
if not any(c.isupper() for c in password):
return 'NO_CAPITAL_LETTER_PASSWORD'
return True
이 함수에 있는 if문 두개를 람다 표현식을 이용하여 다음과 같은 형식으로 작성해야 한다.
아래의 lambdas
리스트 안에 두 개의 람다 표현식을 작성해야하며 주석으로 표시된 프린트가 출력결과로 나와야 한다.
lambdas = [
]
def check_password_using_lambda(password):
for f in lambdas:
if f(password) is not None:
return f(password)
return True
print( check_password_using_lambda('123') ) # SHORT_PASSWORD
print( check_password_using_lambda('12356789f') ) # NO_CAPITAL_LETTER_PASSWORD
print( check_password_using_lambda('123456789fF') ) # True
람다에서 if절을 사용하려면 무조건 else도 같이 적어줘야 하는게 룰이다.
첫 번째 if문을 람다식으로 바꾸어 보았다.
# if len(password) < 8:
lambda p: "SHORT_PASSWORD" if len(p) < 8 else None
두 번째 if문을 람다식으로 바꾸어 보았다.
# if not any(c.isupper() for c in password):
lambda p: "NO_CAPITAL_LETTER_PASSWORD" if not any(c.isupper() for c in p) else None
문제와 코드를 합쳐보았다.
lambdas = [
lambda p: "SHORT_PASSWORD" if len(p)<8 else None,
lambda p: "NO_CAPITAL_LETTER_PASSWORD" if not any(c.isupper() for c in p) else None
]
def check_password_using_lambda(password):
for f in lambdas:
if f(password) is not None:
return f(password)
return True
print( check_password_using_lambda('123') ) # SHORT_PASSWORD
print( check_password_using_lambda('12356789f') ) # NO_CAPITAL_LETTER_PASSWORD
print( check_password_using_lambda('123456789fF') ) # True
그리고 실행하면!
SHORT_PASSWORD
NO_CAPITAL_LETTER_PASSWORD
True
😎