들어가기 전
- 이 글은 이펙티브 파이썬을 공부하며 작성한 글입니다.
1. Itertools 라이브러리
Itertools 라이브러리에는 이터레이터를 위한 몇 가지 기능들이 추가되어있다. 이터레이터와 관련된 코드가 복잡해지는 경우라면, itertools 라이브러리에서 원하는 기능을 지원하는지 살펴보는 것이 좋을 수 있다.
2. 여러 이터레이터 연결하기
itertools에는 여러 이터레이터를 하나로 합치는데 사용할 수 있는 함수들이 지원된다.
2.1 chain()
it = itertools.chain([1,2,3], [4,5,6])
print(list(it))
>>> [1, 2, 3, 4, 5, 6]
- 여러 이터레이터를 하나의 이터레이터를 합침.
2.2 repeat()
# 3번만 반복하는 Iterator 생성
it = itertools.repeat('hello', 3)
print(list(it))
>>> ['hello', 'hello', 'hello']
# 무한히 반복하는 iterator 생성
c = 2
it = itertools.repeat('hello')
for i in it:
print(i)
if (c := c-1) == 0 :
break
>> hello
>> hello
- 한 값을 계속 반복해서 사용하고 싶을 때, repeat()를 사용한다.
- 2번째 인자에 최대 반복횟수를 정할 수 있음. 정하지 않는 경우 무한히 반복함.
2.3. cycle()
import itertools
it = itertools.cycle([1, 2, 3])
result = [next(it) for _ in range(10)]
print(result)
>>> [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]
- 특정 값들을 규칙적으로 반복하는 이터레이터를 만들고 싶을 때 사용할 수 있음.
2.4. tee
it1, it2, it3 = itertools.tee(['one', 'two'], 3)
print(list(it1))
print(list(it2))
print(list(it3))
>>> ['one', 'two']
>>> ['one', 'two']
>>> ['one', 'two']
- 한 이터레이터를 이용해 동일한 여러 이터레이터를 만들고 싶을 때, tee()를 사용한다.
- 이렇게 만들어진 이터레이터의 소모 속도가 동일하지 않은 경우, 아직 사용되지 않은 이터레이터의 원소를 보관해야하기 때문에 메모리 사용량이 늘어날 수 있다.
2.5. zip_longest
import itertools
keys = ['a', 'b', 'c']
values = [1, 2]
# 여러 이터레이터 동시에 이터레이팅.
it = itertools.zip_longest(keys, values, fillvalue="no value")
print(list(it))
>>>
[('a', 1), ('b', 2), ('c', 'no value')]
- 여러 이터레이터를 동시에 이터레이팅 하고 싶을 때 사용함.
- 긴 이터레이터를 기준으로 이터레이팅함.
- 이 때 짧은 이터레이터에는 fillvalue를 기준으로 값을 채워넣어줌. fillvalue의 기본값은 None임.
3. 이터레이터에서 원소 필터링
이터레이터에서 원소 필터링을 하는 함수가 지원된다.
3.1 islice()
import itertools
values = [n for n in range(1, 11)]
# stop = 5
it1 = itertools.islice(values, 5)
print(list(it1))
# start, stop, step
it2 = itertools.islice(values, 0, 5, 2)
print(list(it2))
>>
[1, 2, 3, 4, 5]
[1, 3, 5]
- 이터레이터를 복사하지 않으면서 원소 인덱스를 이용해 슬라이싱 하고 싶을 때, islice()를 사용하면 됨.
- stop만 지정하는 경우
- start, stop, step을 지정하는 경우
위처럼 사용할 수 있음.
3.2 takewhile()
import itertools
values = [n for n in range(1, 11)]
less_than_seven = lambda x : x < 7
it = itertools.takewhile(less_than_seven, values)
print(list(it))
>>>
[1, 2, 3, 4, 5, 6]
- takewhile은 각 원소마다 주어진 함수로 원소를 평가하고, False를 처음 반환하는 원소를 만나는 경우 종료됨.
- False를 처음 반환하는 원소 이전의 원소들을 이터레이터로 반환함.
3.3 dropwhile()
import itertools
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 6, 5, 4, 3, 2, 1]
less_than_seven = lambda x: x < 7
it = itertools.dropwhile(less_than_seven, values)
print(list(it))
>>>
[7, 8, 9, 10, 11, 6, 5, 4, 3, 2, 1]
- dropwhile은 각 원소마다 주어진 함수로 원소를 평가하고, False를 처음 반환하는 원소를 찾을 때까지 모든 원소를 건너띔.
- False를 처음 반환하는 원소를 찾으면 그 원소 뒷쪽의 원소들 모두를 이터레이터로 반환함. (뒷쪽은 만족하지 않아도 상관없음)
3.4 filterfalse
import itertools
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 6, 5, 4, 3, 2, 1]
less_than_seven = lambda x: x < 7
it = itertools.filterfalse(less_than_seven, values)
print(list(it))
>>>
[7, 8, 9, 10, 11]
- 내장 함수 Filter는 표현식이 true인 원소만 반환한다.
- filterfalse는 표현식이 false인 원소만 반환한다.
'프로그래밍 언어 > 파이썬' 카테고리의 다른 글
Effective Python Item 45. 어트리뷰트를 리팩토링하는 대신 @property를 사용하라 (0) | 2024.01.13 |
---|---|
Effective Python Item 44. Setter, Getter 대신 Attribute를 사용하라. (0) | 2024.01.13 |
이펙티브 파이썬 Item 27. map과 filter 대신 컴프리헨션을 사용하라 (0) | 2023.10.21 |
이펙티브 파이썬 Item 26. functools.wrap을 사용해 함수 데코레이터를 정의하라 (0) | 2023.10.19 |
이펙티브 파이썬 Item 25. 위치로만 인자를 지정하게 하거나 키워드로만 인자를 지정하게 해서 함수 호출을 명확하게 만들라 (1) | 2023.10.19 |