16. 람다 함수




1. 람다(lambda) 함수 정의


  • 람다(lambda) 함수 (or 축약 함수): https://wikidocs.net/64
    • 일반적인 함수를 한 줄의 문(Statement)으로 정의할 수 있는 새로운 함수 정의 리터럴
      • 함수 몸체에는 식(expression)만이 올 수 있다.
    • 대부분의 경우 함수 이름을 정의하지 않으면서 일회성으로 활용할 함수를 정의할 때 활용
    • 구문(syntax)
      • lambda 콤마로 구분된 인수들: 식(expression)

1-1 람다 함수 정의 예

  • 인수가 한 개 있는 람다 함수
In [1]:
f = lambda x: x + 1
print f(1)
2
  • 인수가 두 개 있는 람다 함수를 지니는 변수 지정 및 함수 호출
In [1]:
g = lambda x, y: x + y
print g(1, 2)
3
  • 기본 인수를 지니는 람다 함수 정의
In [99]:
incr = lambda x, inc = 1: x + inc
print incr(10) #inc 기본 인수 값으로 1 사용
print incr(10, 5)
11
15
  • 가변 인수를 지니는 람다 함수 정의
In [100]:
vargs = lambda x, *args: args
print vargs(1,2,3,4,5)
(2, 3, 4, 5)

1-2 람다 함수 사용하기

In [2]:
def f1(x):
    return x*x + 3*x - 10

def f2(x):
    return x*x*x

def g(func):
    return [func(x) for x in range(-10, 10)]

print g(f1)
print g(f2)
[60, 44, 30, 18, 8, 0, -6, -10, -12, -12, -10, -6, 0, 8, 18, 30, 44, 60, 78, 98]
[-1000, -729, -512, -343, -216, -125, -64, -27, -8, -1, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
In [3]:
def g(func):
    return [func(x) for x in range(-10, 10)]

print g(lambda x: x*x + 3*x - 10)
print g(lambda x: x*x*x)
[60, 44, 30, 18, 8, 0, -6, -10, -12, -12, -10, -6, 0, 8, 18, 30, 44, 60, 78, 98]
[-1000, -729, -512, -343, -216, -125, -64, -27, -8, -1, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
  • 람다 함수를 사용하는 코드 예제
In [ ]:
# 더하기, 빼기, 곱하기, 나누기에 해당하는 람다 함수 리스트 정의
func = [lambda x, y: x + y, lambda x, y: x - y, lambda x, y: x * y, lambda x, y: x / y]

def menu():
    print "0. add"
    print "1. sub"
    print "2. mul"
    print "3. div"
    print "4. quit"
    return input('Select menu:')

while 1:
    sel = menu()                     
    if sel < 0 or sel > len(func):   
        continue
    if sel == len(func):             
        break
    x = input('First operand:')      
    y = input('Second operand:')     
    print 'Result =', func[sel](x,y) 
0. add
1. sub
2. mul
3. div
4. quit

2 람다 함수의 활용


  • map, filter, reduce 내장 함수
    • 첫번째 인자: function
      • 첫번째 일반적으로 람다 함수를 인자로 받는다.
    • 두번째 인자: 시퀀스 자료형 (문자열, 리스트, 튜플)

2-1 map 내장 함수

  • map(function, seq)
    • seq 시퀀스 자료형이 지닌 각 원소값들에 대해 function에 적용한 결과를 동일 시퀀스 자료형으로 반환한다.
In [22]:
def f(x):
    return x * x

X = [1, 2, 3, 4, 5]
Y = map(f, X)
print Y
[1, 4, 9, 16, 25]
  • map 내장 함수를 사용하지 않을 때 코드
In [24]:
def f(x):
    return x * x

X = [1, 2, 3, 4, 5]
Y = []
for x in X:
    y = f(x)
    Y.append(y)
print Y
[1, 4, 9, 16, 25]
  • map과 람다 함수를 동시에 사용하는 코드 (가장 추천하는 코드)
In [25]:
X = [1, 2, 3, 4, 5]
print map(lambda x: x * x, X)
[1, 4, 9, 16, 25]
  • range(10)의 모든 값 x에 대해 f = x * x + 4 * x + 5의 계산 결과를 리스트로 구함
In [26]:
Y = map(lambda x: x * x + 4 * x + 5, range(10))
print Y
[5, 10, 17, 26, 37, 50, 65, 82, 101, 122]
  • 각 단어들의 길이 리스트
In [3]:
y = map(lambda x: len(x), ["Hello", "Python", "Programming"])
print y
[5, 6, 11]

2-2 filter 내장 함수

  • filter(function, seq)
    • seq 시퀀스 자료형이 지닌 각 원소값들에 대해 function에 적용한 결과가 참인 원소값들만을 동일 시퀀스 자료형으로 반환한다.
In [ ]:
print filter(lambda x: x > 2, [1, 2, 3, 34])
  • 위 코드는 아래와 동일하다.
In [12]:
y = []
for x in [1, 2, 3, 34]:
    if x > 2:
        y.append(x)
print y
[3, 34]
  • 주어진 시퀀스 내에 있는 정수중 홀수만 필터링
In [ ]:
print filter(lambda x: x % 2, [1, 2, 3, 4, 5, 6])
  • 주어진 시퀀스 내에 있는 정수중 짝수만 필터링
In [ ]:
print filter(lambda x: x % 2 - 1, [1, 2, 3, 4, 5, 6])
  • 특정 범위에 있는 정수만 필터링
In [77]:
def F():
    x = 1
    print filter(lambda a: a > x, range(-5, 5))
    
F()
[2, 3, 4]
  • filter의 결과는 주어진 seq 자료형과 동일함
In [17]:
print filter(lambda x: x > 2, [1, 2, 3, 34])
print filter(lambda x: x > 2, (1, 2, 3, 34))
print filter(lambda x: x < 'a', 'abcABCdefDEF')
[3, 34]
(3, 34)
ABCDEF

2-4 reduce 내장 함수

  • reduce (function, seq[, initial])
    • seq 시퀀스 자료형이 지닌 원소값들에 대해 function 함수를 적용하면서 하나의 값으로 매핑한다.
    • 첫번째 인자인 function 함수는 반드시 두 개의 인자 (예를 들어, x, y)를 받아야 한다.
      • seq 시퀀스 자료형의 각 원소값들은 각 단계별로 y에 순차적으로 들어간다.
      • 함수가 수행된 값은 각 단계별로 x에 순차적으로 들어간다.
    • 추가적으로 제공가능한 세번째 인자인 initial은 첫번째 단계에 x에 할당할 초기값으로 사용된다.
In [13]:
print reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
15
단계 x y reduce
1 0 1 1
2 1 2 3
3 3 3 6
4 6 4 10
5 10 5 15
  • initial 값 할당
In [14]:
print reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 100)
115
  • 1부터 10까지 각 수에 대한 제곱값을 모두 더한 결과 구함
In [15]:
print reduce(lambda x, y: x + y * y, range(1, 11), 0)
385
In [13]:
x = 0
for y in range(1, 11):
    x = x + y * y
print x
385
  • 문자열 순서 뒤집기
In [17]:
print reduce(lambda x, y: y + x, 'abcde')
edcba
단계 x y reduce
1 '' 'a' 'a'
2 'a' 'b' 'ba'
3 'ba' 'c' 'cba'
4 'cba' 'd' 'dcba'
5 'dcba' 'e' 'edcba'

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일