Python 에서 lambda function (or lambda expression)은 anonymous function(익명함수)를 만드는데 사용됨.
- function 형태로 code구현의 재사용을 해야하긴 하지만, def문을 이용하여 만들기에는 너무 간단한 경우 등에 사용된다.
- IIFE(Immediately Invoked Function Expression)로 사용되는 경우도 꽤 있다.
- 일반적인 function을 정의하는 def문과 같은 수준의 기능을 가지지만 복잡한 function body가 필요한 경우엔 적합하지 않음.
- 하나의 expression을 사용하기 때문에, exrepssion에 지나치게 복잡한 처리를 무리해서 집어넣는 형태로 구현해선 안됨.
- lambda는 약간만 복잡해도 알아보기 어렵기 때문에 남용하지 않는게 좋다.
- 간단한 event handler를 만들거나, 간단한 처리를 구현하여 map, filter, reduce 등의 argument로 넘겨주는방식으로 애용된다.
lamba라는 이름은 1930년대 Alonzo Church와 Stephen Kleene가 개발한 lambda calculus에서 유래되었다. Lambda calculus는 일종의 수학적인 시스템으로 함수의 definition과 application을 연구하는데 사용됨.
Syntax
Lambda Function의 일반적인 형식은 다음과 같음.
lambda param0, param1: expression_for_return_value
- 위에서 parameter를 2개 사용하는 lambda expression이지만, 필요한 만큼 parameter들 추가가 가능함.
- lambda expression에서는
- 클론 뒤의 expression (위에서 expression_for_return_value)은 evaluation이 이루어짐.
- evalutation을 통해, expression이 해당 수행 결과에 해당하는 한 value로 reduce되며
- 이 해당 value가 return되는 방식으로 동작.
- 때문에 return문을 따로 만들어주지 않는다.
lambda function을 lambda expression이라고도 하는 이유는
하나의 expression만을 가지기 때문임.
사실 Python Interpreter에서는 lambda function도 일반 function과 똑같이 처리된다.
Anonymous Function
lambda expression은 익명(anonymous)함수이기 때문에,
아래 예와 같이 lambda expression을 참조하는 reference에 할당하여 사용 가능함.
(def문은 바인딩되는 식별자가 있는 것과 다름)
lambda_func = lambda s: print(s)
lambda_func('Hello, Python')
위의 경우를 일반적인 def문을 통한 function로 만들면 다음과 같음.
def test_prnt(s):
print(s)
func_ref = test_prnt
func_ref('Hello, Python')
# 일반 함수는 함수명으로 호출하는게 일반적임.
test_ref('Hello, Python')
Immediately Invokded Function Expression (IIFE)
앞서 본 것처럼 reference를 사용하지 않고 일회성으로 다음과 같이 사용도 가능함.
(lambda s: print(s))('Hello, World')
위에서 선언한 lambda function은 참조하고 있는 변수가 없기 때문에 이후로 다시 사용을 할 수 없음.
해당 line에서만 사용할 간단한 처리를 구현하는 경우 사용되는 방식이며,
Immediately Invokded Function Expression (IIFE) 라고 불림.
간단한 코드를 일회용으로만 사용될 경우에
굳이 def문으로 만들 이유가 없다.
map, filter and reduce
lambda exressioin은
- GUI 구현시 간단한 event handler로 사용되거나,
- map또는 filter등과 함께 많이 사용된다.
Python에서
function이나 lambda는 객체이기 때문에
다른 function 호출시 argument로 넘겨줄 수 있음.
2023.07.15 - [Python] - [Python] first-class object (일급객체)
다음 예제들을 살펴보자.
map
src = [1, 3, 5]
dst = map(lambda x: x**3, src)
print(list(dst)) # 결과는 다음과 같음 : [1, 27, 125]
- map은 iterator를 반환하므로
- list 로 바꾸어주는 처리를 해야 제대로 item들을 출력해준다.
위의 예는 src의 item들 각각을 세제곱한 결과를 item으로 가지는 sequence를 얻게 됨.
- 두번째 argument로 들어오는 iterable 객체가 가지는 각 item들에
- 첫번째 argument로 주어진 function(위의 예에선 lambda function)을 적용한다.
두 개의 list를 element-wise로 빼고 이에 절대값을 취해 새로운 list를 얻는 방법은 다음과 같이 구현 가능함.
src0 = [1, 7, 5]
src1 = [2, 3, 8]
dst = list(map(lambda x: abs(x[0]-x[1]), zip(src0,src1)))
print(dst) # 결과는 다음과 같음: [1, 4, 3]
filter
다음의 예는 filter와 함께 사용되는 경우이다.
src = [1,2,3,4,5]
dst = filter (lambda x: x > 3, src)
print(list(dst)) # 결과 : [4, 5]
- 두번째 argument로 들어오는 iterable 객체가 가지는 각 item들에
- 첫번째 argument로 주어진 function(위의 예에선 lambda function)을 적용한다.
- 해당 function은 True와 False를 반환하며,
- True인 경우엔 반환되는 iterator객체에 현재 item이 추가되나,
- False인 경우엔 추가되지 못함.
functools.reduce
functools 모듈의 reduce도 map과 filter만큼 lambda expression과 함께 사용된다.
reduce와 함께 사용될 때는, 앞서 살펴본 map과 filter의 경우와 달리 lambda expression은 두 개의 parameter를 사용하다.
- 첫번재 parameter는 현재 상태로 이전 처리 결과가 할당되고, (아래 예에서
i
) - 두번째 parameter는 현재의 item이 할당되는 방식으로 동작한다 (아래 예에서
j
) - 맨 처음에는 첫번째 item이 첫번째 parameter로, 두번째 item이 두번째 parameter로 할당.
다음 예제는 sequence의 모든 item의 합을 구한다.
from functools import reduce
src = [1,2,3,4,5]
dst = reduce(lambda i,j: i+j, src)
print(dst) # 결과 : 15
'Python' 카테고리의 다른 글
[Python] 특정 점에서 직선에 수선의 발 구하기. (0) | 2023.07.11 |
---|---|
[Python] atan2 (1) | 2023.07.10 |
[Python] os 모듈의 함수들 : file과 directory 관련 (0) | 2023.07.04 |
[Python] binary file: write and read (0) | 2023.07.04 |
[Python] Text File: read and write (0) | 2023.07.04 |