lambda ~~ 하는 구문을 많이 봤을텐데, 이를 람다식이라고 한다.
람다는 ‘익명함수’ 라고 불리는데, 말 그대로 이름이 없는 함수이다.
코드로 확인해보면
# 일반적인 함수 방식
def add_10(x): # 함수의 '이름'이 있다.
return x + 10
# 위 add_10 함수를 람다로 표현하면
lambda x: x + 10
도식화 시켜보면 생각보다 단순하다.
출처: 파이썬 코딩 도장(https://dojang.io/mod/page/view.php?id=2359)
def add_10(x, y=10, z=20):
return x + y + z
lambda x, y=10, z=20: x + y + z
lambda x, y, z: x * z
# print 하면 람다함수임을 알려준다
print(lambda x: x+1) # <function <lambda> at 0x7fdf9e346670>
# 그럼 바로 호출은?
print( (lambda x: x + 1)(10) ) # 11
# 변수에 익명함수 할당
add_1 = lambda x: x + 1
print( add_1(15) ) # 16
lambda 함수는 보통 map, filter, reduce 함수와 함께 병행하여 사용된다.
이 3개 함수들은 인자에 함수를 넘겨받는데, 이를 일반 함수로 선언하지 않고 간단하게 끝내기 위해서!
# 파이썬 내장함수를 써서 단순치환!
list(map(int, "123456")) # [1, 2, 3, 4, 5, 6]
# [ int(1), int(2), int(3) ... int(6)]
# 넘겨받은거에 1씩 더해서 저장하고 싶은데..?
# Case 1) int 를 그냥 넣을 수 있었으니까, 여기에 연산을 하면 되나?
list(map(int(x)+1, "123456")) # NameError: name 'x' is not defined
# int(x) 를 인식할 수 없다.
# Case 2) 그럼 함수를 선언해서 사용하면 되겠네
def add_1(x):
return int(x) + 1
list(map(add_1, "123456")) # [2, 3, 4, 5, 6, 7]
# 처음 1, 2, 3 ... 6을 1씩 잘 더해줬다.
# Case 3) 고작 1만 더하려고 했는데 함수까지 선언해야돼? map에다 선언해야지?
list(map(def add_1(x): return int(x)+1, "123456"))
# SyntaxError: invalid syntax 발생..!!
# map에서 함수를 받지만, 그렇다고 def로 함수를 선언할 순 없다.
# Case 4) 그럼 간단하겐 못하나?
list(map(lambda x: int(x)+1, "123456")) # [2, 3, 4, 5, 6, 7]
# 함수를 def로 선언하지 않아도 되네?
# 물론 이렇게도 가능!
add_1 = lambda x: int(x) + 1
list(map(add_1, "123456"))
"""
filter() 는 조건에 맞는 값만 골라서 되돌려 준다.
0~10 사이 수 중 짝수만 리스트로 넣기
"""
# 리스트 표현식으로 필터링
even_numbers = [i for i in range(10) if i % 2 == 0] # [0, 2, 4, 6, 8]
# filter()를 써보자
# Case 1) 당연히 함수를 선언해서 써도 된다
def is_even(x):
if x % 2 == 0:
return True
return False
even_numbers = list(filter(is_even, range(10))) # [0, 2, 4, 6, 8]
여기서 잠깐, 알고 가면 좋을 내용..
if else 한줄로 표현하기
# 홀짝을 판별하는 함수가 있다고 가정하면
y = 3
def odd_even(x):
if x % 2 == 0:
return "짝수"
else:
return "홀수"
odd_even(y) # "홀수"
# 이런 단순 if-else 구조를 한줄에 표현하면
def odd_even(x):
return "짝수" if x % 2 == 0 else "홀수"
# 함수여서 return 으로 값을 돌려줬다
다시 코드로 돌아가서
def is_even(x):
return True if x % 2 == 0 else False
# 사실 단순 True / False 라면 if 문도 필요가 없다
# return x % 2 == 0
even_numbers = list(filter(is_even, range(10))) # [0, 2, 4, 6, 8]
# Case 2) 람다를 활용해보자
even_numbers = list(filter(lambda x: True if x % 2 == 0 else False, range(10)))
# 사실 여기선 if else 가 없이 비교 연산만으로 가능하잖아? 홀수를 뽑으면
odd_numbers = list(filter(lambda x: x % 2 != 0, range(10))) # [1, 3, 5, 7, 9]
# 제일 깔끔!!
reduce( ) 와 함께 사용
값을 누적시킬 때 reduce() 를 사용한다.
reduce는 기본 내장함수가 아니라 functools 모듈에서 제공한다.
# 두 값을 더하는 함수를 만들어 보자
def my_sum(x, y):
return x + y
# 일반적으로 구현하면
total_sum = 0 # 누적 할 변수를 선언하고
for i in range(1, 6):
total_sum += i # 반복문으로 누적시켜야 한다
print(total_sum) # 15
# 코드가 좀 긴.. 듯 한데
# reduce로 표현해보자
from functools import reduce
reduce(my_sum, range(1, 6)) # 15
람다로 표현해보자
reduce(lambda x, y: x + y, range(1, 6)) # 15
# 팩토리얼도 가능하다
reduce(lambda x, y: x * y, range(1, 6))
얼마나 간소해졌을까
# 단순 서술
def my_sum(x, y):
return x + y
total_sum = 0
for i in range(1, 6):
total_sum += i
print(total_sum) # 15
reduce(lambda x, y: x + y, range(1, 6))
reduce로 식을 엄청 간소화 시킬 수 있는것을 확인했다.
하지만 이 reduce는 코드가 복잡해질 수록 코드가 무엇을 의미하는지 파악이 힘들어지는 부분이 있어 Python 3 부터는 reduce 를 내장함수에서 제거했다고 한다