강의노트 03. 파이썬 lambda, map, filter, reduce, dic
03 Apr 2017 |패스트캠퍼스 컴퓨터공학 입문 수업을 듣고 중요한 내용을 정리했습니다. 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
lambda 함수
- 익명함수 : 메모리를 아끼고 가독성을 향상시킨다. pythonic
- 일반적인 함수는 객체를 만들고, 재사용을 위해 함수 이름(메모리)를 할당한다.
# lambda 인수1, 인수2, ... : 인수를 이용한 표현식
>>> sum = lambda a, b: a+b
>>> sum(3,4)
7
lambda는 왜 쓰는가?
- 익명함수이기 때문에 한번 쓰이고 다음줄로 넘어가면 힙(heap) 메모리 영역에서 증발
- (참고) 가비지 컬렉터 (참조하는 객체가 없으면 지워버린다)
- 파이썬에서는 모든것이 객체로 관리 되고 각 객체들은 레퍼런스 카운터를 갖게 된다. 이 카운터가 0 즉, 그 누구도 참조하지 않게 된다면 메모리를 환원 하게 된다.
map 함수
- 내장함수
- 입력받은 자료형의 각 요소가 합수에 의해 수행된 결과를 묶어서 map iterator 객체로 리턴
# 문법
map(f, iterable)
# 함수(f)와 반복 가능한 (iterable) 자료형을 입력으로 받는다.
map 예시문제
- map으로 짜면 게으른 연산을 진행해서 메모리를 크게 절약할 수 있다.
- map의 연산 결과는 map iterator 객체로 리턴한다.
# Input : li = [1, 2, 3]
# Output : result = [1, 4, 9]
# 풀이
result = list(map(lambda i: i ** 2 , li))
(참고) 게으른 연산
- 필요할 때 가져다 쓴다.(예: map함수의 결과 객체)
- iterator 객체
- next() 메소드로 데이터를 순차적으로 호출 가능한 object
- 마지막 데이터까지 불러 오면 다음은 StopIteration exception 발생
- iterable한 객체를 iterator 로 변환하고 싶다면, iter() 라는 built-in function 을 사용
- for 문으로 looping 하는 동안, python 내부에서는 임시로 list를 iterator로 자동 변환
# ex1.
li = [1, 2, 3]
result = map(lambda i: i * i, li)
next(result) # 1
next(result) # 4
next(result) # 9
next(result) # StopIteration 발생
# ex2.
>>> x = [1,2,3]
>>> type(x)
<class 'list'>
>>> y = iter(x)
>>> type(y)
<class 'list_iterator'>
3항 연산자
# if else문
def func(a):
if a > 10:
return 'a가 10보다 크다'
else:
return 'a가 10보다 작다'
# 3항 연산자
def func2(a):
return 'a가 10보다 크다' if a > 10 else 'a가 10보다 작다'
3항 연산자 예시문제
- 조건이 3개일 경우에도 3항 연산자 사용이 가능하다.
#Input : li = [-3, -2, 0, 6, 8]
#Output : ['음수', '음수', 0, '양수', '양수']
#풀이 1
>>> ['양수' if i > 0 else ('음수' if i < 0 else 0) for i in li]
>>> ['음수', '음수', 0, '양수', '양수']
#풀이 2
>>> list(map(lambda i: '양수' if i > 0 else ('음수' if i < 0 else 0), li))
>>> ['음수', '음수', 0, '양수', '양수']
filter 함수
- filter(함수, literable)
- 두번째 인수인 반복 가능한 자료형 요소들을 첫번째 인자 함수에 하나씩 입력하여
리턴값이 참인 것만
묶어서 돌려준다. - 함수의 리턴 값은 참이나 거짓이어야 한다.
li = [-2, -3, 5, 6]
# 양수만 반환하는 리스트
def ft(li):
result = []
for e in li:
if e > 0:
result.append(e)
else:
pass
return result
# filter 함수 사용시
def positive(x):
return x > 0
list(filter(positive, li))
# filter + lambda 함수 사용시
list(filter(lambda x: x > 0, li))
reduce 함수
- python3 부터 내장함수에서 빠짐
- reduce(function, iterable[, initializer])
- 문서
from functools import reduce
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
# = ((((1+2)+3)+4)+5)
reduce 함수 예시문제 1
from functools import reduce
# 문제1. 전통적으로 최대값 구하기
def maximum(li):
default = 0
for e in li:
if default < e:
default = e
return default
maximum(li)
# 문제1. reduce 활용하여 최대값 구하기
reduce(lambda a,b: a if a > b else b ,li)
(참고) 문자별 갯수 구하기 알고리즘
or, and
>>> [1,2,3] and []
>>> []
>>> [1,2,3] or []
>>> [1,2,3]
>>> bool([1,2,3] or [])
>>> True
dictionary 관련함수
- dict : dictionary 만들기
- .get() : key를 통하여 value 값 검색
- .update() : dictinary 요소 업데이트
# dict
>>> dic = dict(one=1, two=2)
>>> print(dic)
>>> {'one': 1, 'two': 2}
# .get()
>>> dic['three'] # 해당 key 값이 없으면 KeyError
>>> dic.get('three') # 해당 key 값이 없으면 None
>>> dic.get('three', 3) # 해당 key 값이 없으면 & 디폴트 값이 있으면 디폴드 값 반환
# .update()
>>> dic.update({'three': 3}) # dictinary에 요소를 업데이트, 리턴 값은 None
>>> dic
>>> {'one': 1, 'three': 3, 'two': 2}
## update와 동시에 결과 값을 반환하고 싶을 때
>>> dic.update({'four': 4}) or dic
>>> {'four': 4, 'one': 1, 'three': 3, 'two': 2}
문제 (중요)
# Input : data = ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c']
# Output : {'a': 3, 'b': 2, 'c': 3}
# 풀이 1
>>> reduce(lambda a, b: a.update({b: a.get(b, 0) + 1}) or a,
data,
{}
)
# reduce(lambda a, b: a.update({b: a.get(b, 0) + 1}) or a, data,{})
# 풀이 2
# 풀이 1이 풀이 2보다 더 효율적이다 (변수, itorator 객체 생성 메모리 절약)
>>>result = { i : 0 for i in data} # {'a': 0, 'b': 0, 'c': 0}
>>>for i in data:
result[i] += 1
>>>result
>>>{'a': 3, 'b': 2, 'c': 3}