본문 바로가기
wecode/TIL 정리

위코드 Pre Course - 파이썬의 Lambda

by 왕거 2020. 7. 25.

파이썬에서 인라인 함수를 정의할 때 사용하는 Lambda에 대해서 정리한다.

 

Lambda란?

  • 람다라고 읽음
  • 인라인 함수를 정의할 때 사용하며, 익명 함수(Anonymous Functions) 또는 람다 표현식(Lambda Expression)
    • <lambda> + <인자들> + <:> + < 표현식>
  • 람다와 일반 함수의 차이점은?
    • 함수는 이름이 있고, 내부에 여러 라인으로 로직을 구성할 수 있으며, return을 통해서 반환 값을 지정해 줄 수 있다.
    • 람다는 이름이 없고, 한줄로 로직을 구성해야 하며, return을 사용하지 않아도 결과를 반환한다.
  • 람다의 로직에 다시 람다를 넣을 수 있다. == "nested될 수 있다."
  • 장점
    • 많은 함수를 사용하게 될 때 생기는 함수명 충돌과 같은 문제의 발생 가능성을 낮출 수 있다.
    • 적절하게 표현된 람다는 코드의 가독성을 향상시킨다.
  • 단점
    • 에러가 발생했을 때 Traceback로부터 어떤 지점에서 발생한 문제인지 확인할 수 없다.
      • 람다를 사용하려면 표현식과 인자를 확실하게 검증해야 한다!
  • 사용하면 좋은 상황
    • 간단한 콜백 함수를 여러개 선언해야 하는 상황
# 일반 함수와 람다 비교
# 일반 함수 선언 방식 사용
def square(x): 
    return x ** 2

def power_3(x): 
    return x ** 3

def power_4(x):
    return x ** 4

powers = [ square, power_3, power_4 ]

for f in powers:
    print( f(2) )

########################################

# 람다 방식 사용
Lambdas = [
    lambda x : x ** 2,
    lambda x : x ** 3,
    lambda x : x ** 4
]

for lambda_func in Lambdas:
    print( lambda_func(2) )

 

Lambda 사용법

# 람다의 예제
f = lambda x, y, z : x*y*z

print(f)
print(f(1,2,3))

############################
# 실행 결과
<function <lambda> at 0x0307A388>
6

 

Assignment

 

  • 다음 코드를 실행해보고 출력되는 결과를 확인해보고 types 모듈에 어떤 타입들이 있는지 조사해보자.
# Assignment 1
import types

f = lambda x,y,z : x+y+z

print(f)
print(type(f))
print(type(f) == types.LambdaType)

#######################################
# 실행 결과
<function <lambda> at 0x00F0A388>
<class 'function'>
True
  • types 모듈에 있는 타입들
    • 기본 자료형 타입
      • integer, float, set, string, list등등
    • AsyncGeneratorType
      • 비동기 제너레이터 함수가 만든, 비동기 제너레이터-이터레이터 객체의 타입
      • 파이썬 3.6에서 추가됨
    • BuiltinFunctionType, BuiltinMethodType
      • 내장 함수와 내장 메소드의 타입
    • CellType
      • 셀 객체의 타입
      • 자유변수에 대한 컨테이너로 사용된다.
      • 파이썬 3.8에서 추가됨
    • ClassMethodDescriptorType
      • dict.__dict__['fromkeys']와 같은 일부 내장 데이터형의 연결되지 않은(unbound) 클래스 메서드의 타입
    • CodeType
      • compile()이 반환하는 것과 같은 코드 객체의 타입
    • CoroutinType
      • async def 함수가 만든 코루틴 객체의 타입
    • FrameType
      • 트레이스백 객체의 tb_frame에서 발견되는 것과 같은 프레임 객체의 타입
    • GeneratorType
      • 제네레이터 함수가 만든 제네레이터-이터레이터 객체의 타입
    • GetSetDescriptor
      • PyGetSetDef가 있는 확장 모듈에서 정의된 객체의 타입
      • 객체 어트리뷰트에 대한 디스크립터로 사용된다.
    • MappingProxyType
      • 매핑의 읽기 전용 프록시
      • 매핑 항목에 대한 동적 뷰를 제공
    • MemberDescriptiorType
      • PyMemberDef가 있는 확장 모듈에서 정의된 객체의 타입
      • 표준 변환 함수를 사용하는 간단한 C 데이터 멤버의 디스크립터로 사용
    • MethodType
      • 사용자 클래스 인스턴스의 메소드 타입
    • Traceback
      • 트레이스백 객체의 타입
    • 참고 페이지
  • 비밀번호의 길이와 대문자 포함여부를 확인하는 함수를 람다로 변환해보자
# Assignment 2
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

 

# 위 함수를 람다를 사용한 방식으로
lambdas = [ 
    lambda i : 'SHORT_PASSWORD' if len(i) < 8 else None,
    lambda i : 'NO_CAPITAL_LETTER_PASSWORD' if not any(l.isupper() for l in i) 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') )
print( check_password_using_lambda('12356789f') )
print( check_password_using_lambda('123456789fF') )

################################################################3
# 실행 결과
SHORT_PASSWORD
NO_CAPITAL_LETTER_PASSWORD
True
  • 람다 표현식에 조건문을 거는게 조금 까다로움
    • if 조건문을 사용하면 else 케이스를 꼭 추가해주어야 한다.