lambda
lambda를 설명하기에 앞서 다음과 같은 함수가 있다고 해보자.
def increment(x):
return x + 1
increment(33) # 34
이것을 lambda를 이용하면 단 한 줄로 나타낼 수 있다.
increment_lambda = lambda x: x+1
increment_lambda(33) # 34
이렇게 하면 increment_lambda
라는 함수는 아까 만든 increment
함수와 완벽히 똑같은 함수가 된다.
lambda의 구조을 살펴보면
lambda [입력값] : [반환값]
이렇게 간단하지만 함수에서 있어야 할 것은 다 있다. 하지만 위의 예제만 보면 왜 굳이 lambda를 써야되는 지 잘 와닿지 않는다.
다음에 나오는 map, reduce, filter를 사용해보면 lambda가 언제 쓰이면 좋은지 바로 느낄 수 있을 것이다.
map
map( [함수], [배열])
map 함수는 배열에서 원소를 하나씩 꺼내어 함수를 적용시킨 결과를 다시 새로운 배열에 담아 반환해준다.(정확히 말해서는 map
클래스의 객체를 반환하는 것이고, list
함수를 적용했을 때 진정한 배열이 된다. 그래서 일반적으로 list
함수와 같이 사용된다.)
간단한 예제를 보자.
def square(x):
return x**2
list(map(square,[1, 2, 3])) # [1, 4, 9]
각각의 원소를 제곱한 [1, 4, 9]라는 새로운 list가 출력될 것이다.
여기서 square 함수는 단지 map 함수의 argument로 넣기 위해서 위에 따로 만들었다. 이 때 아까 배운 lambda를 쓰면 위의 코드를 단 한 줄로 바꿀 수 있다.
list(map(lambda x: x**2, [1, 2, 3])) # [1, 4, 9]
위의 예제처럼 함수가 한 줄로 표현될 만큼 구성이 단순하고, 한 번만 사용하는 함수인 경우 lambda는 매우 유용하다. 그 말은 반대로 복잡하거나 자주 사용하게 되는 함수라면 lambda를 사용하지 않는 것이 더욱 효율적일 것이다.
reduce
reduce( [함수], [배열], [초기값])
reduce는 배열에서 두 원소의 함수 출력값이 뒤에 나오는 원소와 함께 또 다시 함수의 argument로 들어가며 이 과정이 순차적으로 반복되는 방식이다.
여기서 함수는 두 개의 parameter를 받는 함수여야하고 초기값은 생략될 수 있다. 초기값이 있으면 초기값과 배열의 첫 원소가 맨 처음 함수로 전달되고. 초기값이 없다면 배열의 첫 번째와 두 번째 원소가 맨 처음 함수로 전달된다.
말보다는 코드를 직접 보는 것이 이해가 빠를 것이다.
import functools
def sum(x,y):
print((x,y))
return x + y
functools.reduce(sum, [10, 20, 30, 40, 50]) # 150
reduce 함수를 쓰기 위해서는 우선 functools
라는 라이브러리를 import해야 한다. 위와 같이 sum
함수 중간에 print
함수를 넣어보면 reduce 함수의 연산과정을 한 눈에 확인할 수 있다.
아까와 마찬가지로 lambda를 이용하면 한 줄로 코드를 적을 수도 있다.
functools.reduce(lambda x,y: x+y, [10, 20, 30, 40, 50])
이런 식으로 reduce 함수와 lambda를 이용하여 최댓값을 찾는 함수도 코드 한 줄로 구현할 수 있다.
functools.reduce(lambda x,y: x if x>y else y, [1, 9, 3, 5, 6, 4])
filter
filter( [함수], [배열])
filter는 배열에 있는 각각의 원소들을 함수에 parameter로 넘겨주어 함수의 출력값이 True
인 경우에만 그 원소를 새로운 배열에 담아 반환한다.
list(filter(lambda x: x>3, [1, 2, 3, 4, 5])) # [4, 5]
4, 5만 3보다 크므로 [4, 5]로 출력된다.
이번엔 lambda, map, filter를 모두 활용하여 주어진 배열에서 자료형이 int
인 원소만 뽑아낸 다음, 각각 제곱한 수들을 새로운 list
로 만들어 낼 수도 있다.
complicated_list = [1, 2, "jupiny", {}, [], 4, 5]
list(map(lambda x: x**2, list(filter(lambda x: isinstance(x,int),complicated_list)))) # [1, 4, 16, 25]