[python] 람다(lambda), 함수형 fileter / map / reduce
아무래도, 파이썬에서는 filter, map, reduce 보단 list comprehension을 사용하는게 더 pythonic하다는 의견이 주류인 것 같다.
https://www.artima.com/weblogs/viewpost.jsp?thread=98196
[python] Comprehension, Generator / iterator VS iterable / itertools
lambda
람다식은 `` filter, map, eval``같은 larger expression에 끼워서(inline) 사용하는 경우 가독성을 높여준다.
복잡한 상황에서는 명확한 ``py def``를 사용하는 편이 가독성이 더 좋다.
그리고 이런 식으로 람다식을 변수에 할당해서 쓰는 것은 지양해야 한다. (PEP8)
```py
sum = lambda a, b: a+b # No
def sum(a, b): return a+b # Yes
```
람다식을 사용하면 filter를 사용할 때 만들어야 하는 조건 함수를 대체할 수 있다.
```py
print(list(filter(lambda x: x > 0, [1, -3, 2, 0, -5, 6])))
```
자바 8에서의 람다식과 비슷하지만 함수형 인터페이스를 구현할 필요가 없다는 점이 편리하고 반복문을 사용할 수 없는 eval 등에 사용할 수 있다.
map / filter / reduce
- numpy 브로드캐스트
- list comprehension
- generator
filter(function, iterable)
필터를 사용하면 반복문을 사용해 순회하며 비교해야 하는 작업을 간단히 처리할 수 있다.
즉 function에는 조건역할을 하는 function이 들어가야 한다. ( ``py return expr`` )
* 이렇게 ``py True/False``를 반환하는 함수를 predicate(술어)라고 한다.
리스트에서 양수만 추출해서 리스트로 만드는 작업을 필터로 처리한 예다.
```py
def positive(x):
return x > 0
print(list(filter(positive, [1, -3, 2, 0, -5, 6])))
```
filter 함수는 filter object를 반환하므로, 이를 list()로 묶어 list로 만들어야 사용할 수 있다.
map(function, iterable)
iterable에서 각각의 원소에 대해 function을 적용한 결과를 묶어서 리턴해준다.
filter와 비슷하다고 생각할 수 있겠지만, filter는 function에 넘겨 수행한 결과가 True인 iterable의 항목을 추출하는 것이기 때문에 결과값을 추출하는 map과는 완전히 다르다.
또한 function이 조건함수여야만 하는 것은 아니다.
```py
print(list(map(lambda x: x*2, [1, 2, 3, 4, -1, -2, -5, -10])))
=>[2, 4, 6, 8, -2, -4, -10, -20]
```
filter의 경우 x*2를 입력하면 x*2의 결과가 항상 참이기 때문에 원래 리스트를 반환한다.
map을 filter처럼 사용하면 다음과 같이 ``py True/False``가 반환된다.
```py
print(list(map(lambda x: x>0, [1, 2, 3, 4, -1, -2, -5, -10])))
=>[True, True, True, True, False, False, False, False]
```
filter와 map을 조합해서 사용하기
>>> list(map(lambda x: x*2, filter(lambda x: x>0, [1, 2, 3, 4, -1, -2, -3, -4])))
[2, 4, 6, 8]
reduce
flatMap (custom)
- 파이썬에서는 기본적으로 flatMap을 지원하지 않아서, 직접 정의해서 사용해야 함.
- flatten2 방법은 list comp. 사용해서 자체 문법만으로 해결할 수 있어 간결하다는 장점.
- flatten 방법은 iter 요소를 사용해서 지연 평가 가능하다는 장점 (테스트는 안해봤는데 아마 될 것 같다.)
```python
from itertools import chain
def flatten(iterable):
return chain.from_iterable(iterable)
def flatten2(iterable):
return [j for i in iterable for j in i]
def flatMap(func, iterable):
return flatten(map(func, iterable))
```
파이썬 map filter reduce의 단점은...ㅠ
자바나 다른 언어 같은 경우는 위에서부터 필터 걸리고 맵 걸리고... 이런 식으로 위에서부터 데이터 처리 흐름 대로 읽어나갈 수 있는데
파이썬은 밑에서부터 list가 있고 그 다음 필터를 할거고... 그 다음 맵을 하고... 그 다음 리스트로 만든다. 로 읽어야 함.
코드는 위에서 부터 읽는게 편하기 때문에... 이런게 참 불편하다.
그래서 그냥 파이썬에서는
```python
t1 = filter(..., x_list.items())
t2 = map(..., t1)
result_list = list(t2)
```
차라리 이렇게 쓰는게 낫지 않을지...
https://github.com/EntilZha/PyFunctional#simple-example 라이브러리를 쓰면 chaining이 가능하긴 하다.
'Languages & Frameworks > Python' 카테고리의 다른 글
[python] with / try-except (0) | 2017.07.02 |
---|---|
[python] directory parse / glob / pathlib (0) | 2017.07.02 |
[python] Comprehension, Generator / iterator VS iterable / itertools (0) | 2017.07.02 |
[python] binary data와 16진수 / struct.pack (0) | 2017.05.09 |
[python] 출력 관련 : 문자열, str <> bytes, bytearray (2) | 2017.05.09 |