프로그래밍/python

파이썬 람다(lambda) 함수

콘파냐 2015. 10. 31. 11:24
반응형

파이썬의 람다함수는 매우 직관적입니다. C++11에서도 람다함수가 등장했는데 파이썬의 문법과 비교하면 복잡하죠. 아마 파이썬 문법 익숙하게 되면 C++ 람다함수를 보고 황당해 할겁니다.

람다함수란?

람다함수란 람다식, 또는 람다 표현식, 익명함수 등으로 알려져 있습니다. 실제로 이름이 없이 정의되어 사용됩니다.

이 녀석은 함수와 동일한 녀석인데 실제로 사용을 하는 건 자기 취향이라고 생각합니다. 없어도 되는데 보통 어디에 사용되냐 물으면 언어들마다 특색이 있기에 한마디로 정의할 수는 없겠지만, 우선 대부분의 언어들이 람다함수(람다식)을 지원하는 추세로 바뀌었기 때문에 소스를 읽기 위해서라도 알아둘 필요가 있습니다.

실제 함수와 비교

lambda x,y:x+y 는 람다식입니다. 여기서 f는 람다식의 위치를 받는 함수 포인터지 람다식의 이름이라고 생각하면 안됩니다. 람다식은 이름이 없고 이름없이 그대로 사용될 수도 있습니다.(예를 들어 함수의 인수로 바로 사용가능)

 

인수

f = lambda x, y:x+y 라고 했는데, 간단히 인수를 조작해 보겠습니다.

우선 첫번째 식은 f = f+x; 라고 생각하시면 됩니다.(이 람다식은 함수로 표현하는 것보다 편해보이죠.) 두 번째 x=1, f=2는 디폴트 인수를 말하구요. 디폴트 인수는 인수 값을 정해주지 않으면 이 값으로 하겠다는 뜻입니다.(이건 람다함수 뿐 아니라 일반 함수에서도 통용됩니다.)

 

함수의 인수로 사용 예

파이썬에서 함수를 다른 함수의 인수로 사용하는 방법은 쉽습니다. 람다함수도 마찬가지입니다.

다음 예는 일반함수를 함수의 인수로 사용한 예입니다.

다음은 일반함수를 람다함수의 인수로 사용한 예입니다.

그런데 보통은 다음과 같이 람다함수를 일반함수의 인수로 사용하죠.

가독성의 차이가 느껴지시나요?

여기서 함수를 인수로 사용하는 법은 간단히 설명하겠습니다.

f(g, a, b) 에서 g, a, b의 타입은 리턴값을 봐야지 알 수 있습니다. g(a,b)가 리턴값이므로 함수를 인수로 사용할 때 f(함수포인터, 인수, 인수) 이런 식이 되어야 합니다. 함수 포인터가 가리키는 것은 함수객체입니다. 여기서 함수 객체 대신 람다식을 쓴 것은 람다식 자체가 함수 객체이기 때문입니다. 좀 더 자세히 이야기하면 함수 객체는 실제로 메모리 상에 위치한 인스턴스를 이야기합니다. 아무튼

g(a,b) 라는 함수의 메모리를 가리키는 값은 g 입니다.

이렇게 주소가 나오죠? 람다식도 같은 타입입니다. 람다식을 f=lambda x,y:x+y 이렇게해서 f(x,y) 이렇게 사용하는 원리가 이해가시죠?

간단한 예를 하나 더 들겠습니다.

파이썬의 내장함수 중 사상함수가 있습니다. 사상함수는 우리가 중고등학교 때 배운 사상(함 수 f(x)=2x+1 에서 f를 사상이라고 한다.) map이란 함수인데 사상값과 인수값(정의역)(리스트)을 넣어서 (치역값)을 결과(리스트)로 반환합니다.

map(사상, 인수,인수,...) 이런 식입니다. 인수는 여러 개가 올 수 있습니다. 위 예처럼 사상 f(x,y) = x*y 이런 경우는 인수가 2개가 되죠.

 

가변인자

가변인자(가변인수) 또한 함수나 람다함수나 사용법이 같습니다. 가변인자는 인자의 개수가 정해지지 않았으므로 0개부터~원하는 만큼 기입하면 됩니다. 가변인자는 튜플(tuple)형과 사전(dictionary)형이 있습니다.

*x 튜플형

이젠 람다식으로 표현해보겠습니다.

arg가 튜플(tuple) 형이므로 x도 튜플형이 되어야 합니다.

 

**x 사전형

사전형 자료집합이 생겼네요. 인수의 개수는 가변입니다.

 

일반 함수와 람다 함수의 차이점

예를 들어 람다함수는 :를 사이로 인수:식 형태로 식의 값이 리턴이 됩니다. 문법이 심플하지만 지역변수를 만들 수 없습니다. 또한 파이썬의 함수는 C/C++과 달리 리턴값을 두 개 이상 정할 수 있습니다. 반면에 파이썬의 람다식은 1개만(1개의 식만) 가능합니다.

그래도 람다식을 사용하면 매우 간단한 식의 경우에는 인수에 람다식을 그대로 넣어서 가독성이 좋아지고 불필요한 함수 정의 없이 사용하여 코드를 깔끔하게 할 수 있습니다.

람다함수에서 지역변수를 정의할 수는 없지만, 다음과 같이 지역변수 대신 외부 변수를 사용할 수 있습니다.(C++의 람다함수는 외부 변수를 캡쳐하여 사용하는 문법이 존재합니다. [캡쳐]) 파이썬은 그냥 외부에 정의만 해 놓으면 가까운 영역부터 찾아서 사용합니다.

참고 : C++에서는 캡쳐하는 대상을 직접 조작하고 캡쳐하는 방식(복사=, 참조&)를 정할 수 있습니다. 그리고 mutable 키워드로 상수로 캡쳐할지 말지를 정합니다.대충 봐도 꽤 복잡하죠?

위 람다함수를 C++로 표현해 보면 이렇습니다.

[c](int x)->int{return x+c;}(1);

반응형