chain, count, izip, imap, islice, tee, cycle, repeat, dropwhile, takewhile, ifilter, groupby
ython 에서 제공하는 자신만의 반복자를 만드는 모듈
import itertools
리스트( lists/tuples/iterables ) 를 연결
letters = ['a', 'b', 'c', 'd', 'e', 'f']
booleans = [1, 0, 1, 0, 0, 1]
decimals = [0.1, 0.7, 0.4, 0.4, 0.5]
print list(itertools.chain(letters, booleans, decimals))
결과 : ['a', 'b', 'c', 'd', 'e', 'f', 1, 0, 1, 0, 0, 1, 0.1, 0.7, 0.4, 0.4, 0.5]
count 는 반복하고자 하는 최대수를 미리 알지 않아도 되는 경우 사용.
from itertools import count , izip
for number, letter in izip(count(0, 10), ['a', 'b', 'c', 'd', 'e']):
print '{0}: {1}'.format(number, letter)
결과: 0: a 10: b 20: c 30: d 40: e
0 에서 시작해서 10씩 5개의 요소에 대해서 필요한 만큼 증가시킴
유사) 시작과 step 만 있는 range 함수
zip () 함수와 유사하지만, 다른점은 iterable 객체를 반환한다.
from itertools import izip
print list(izip([1, 2, 3], ['a', 'b', 'c']))
결과 : [(1, 'a'), (2, 'b'), (3, 'c')]
map () 함수와 거의 동일한 방식으로 작동
from itertools import imap
print list(imap(lambda x: x * x, xrange(10)))
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
반복가능 객체에서 자르고 싶은 만큼 자를 수 있다.
from itertools import islice
for i in islice(range(10), 5):
print i
for i in islice(range(100), 0, 100, 10):
print i
결과 : 0 1 2 3 4
[0 ~ 10] 의 반복가능 객체에서 5번째 안으로 짤라라
결과 : 0 10 20 30 40 50 60 70 80 90
islice () 함수는 slice () 함수와 동일하게 작동
첫 번째 매개 변수는 반복 가능한 객체이고,
두 번째 매개 변수는 시작 색인.
세 번째 매개 변수는 끝 색인
마지막 매개 변수는 각 반복 후에 건너 뛸 수있는 단계 또는 숫자
from itertools import tee
i1, i2, i3 = tee(xrange(10), 3)
print i1
# <itertools.tee object at 0x2a1fc68>
print list(i1)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(i1)
# []
print list(i2)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(i2)
# []
print list(i3)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(i3)
# []
tee () 함수는 두 개의 매개 변수를 사용한다
첫 번째는 반복 가능
두 번째는 만들고자하는 복사본 개수
한번 사용된 레퍼런스는 더 이상 값을 참조 하지 않는다.
r = (x for x in range(10) if x < 6)
print r
# <generator object <genexpr> at 0x2a22870>
i1, i2, i3 = tee(r, 3)
print list(r)
# [0, 1, 2, 3, 4, 5]
print list(i1)
# []
print list(i2)
# []
print list(i3)
# []
이렇게 원본의 제네레이터인 r 을 실행시키면 나머지 복제본들도 다 참조가 끊어진다.
순환 가능한 객체에서 요소를 반복적으로 생성
from itertools import cycle , izip
for number, letter in izip(cycle(range(2)), ['a', 'b', 'c', 'd', 'e']):
print '{0}: {1}'.format(number, letter)
# 0: a
# 1: b
# 0: c
# 1: d
# 0: e
오른쪽 리스트에 따라 한정지어진다.
요소를 반복. 반복되는 개수 지정.
from itertools import repeat
print list(repeat('Hello, world!', 3))
# ['Hello, world!', 'Hello, world!', 'Hello, world!']
필터링 함수.
조건에 맞지 않으면, drop
맞으면, 포함시켜 return
from itertools import dropwhile
print list(dropwhile(lambda x: x < 10, [1, 4, 6, 7, 11, 34, 66, 100, 1]))
# [11, 34, 66, 100, 1]
필터링 함수
조건에 맞는 값이 나올 때까지 모든 요소 반환
from itertools import takewhile
print list(takewhile(lambda x: x < 10, [1, 4, 6, 7, 11, 34, 66, 100, 1]))
# [1, 4, 6, 7]
필터링 함수
조건에 맞는 값을 반환
from itertools import ifilter
print list(ifilter(lambda x: x < 10, [1, 4, 6, 7, 11, 34, 66, 100, 1]))
# [1, 4, 6, 7, 1]
from operator import itemgetter
from itertools import groupby
attempts = [
('dan', 87),
('erik', 95),
('jason', 79),
('erik', 97),
('dan', 100)
]
# Sort the list by name for groupby
attempts.sort(key=itemgetter(0))
# Create a dictionary such that name: scores_list
print {key: sorted(map(itemgetter(1), value)) for key, value in groupby(attempts, key=itemgetter(0))}
# {'dan': [87, 100], 'jason': [79], 'erik': [95, 97]}
key 함수로 itemgetter(0) 를 이용하여 정렬후, 첫번째 요소로 groupby 한다. (정렬 해야 한다.)
from collections import defaultdict
counts = defaultdict(list)
attempts = [('dan', 87), ('erik', 95), ('jason', 79), ('erik', 97), ('dan', 100)]
for (name, score) in attempts:
counts[name].append(score)
print counts
# defaultdict(<type 'list'>, {'dan': [87, 100], 'jason': [79], 'erik': [95, 97]})
defaultdict 사용. 널값에 대한 체크를 생략할 수 있는 편의 를 제공한다.
출처 :
https://www.blog.pythonlibrary.org/2016/04/20/python-201-an-intro-to-itertools/
https://hamait.tistory.com/803