본문 바로가기

프로그래밍/Python

[파이썬 / 기본] itertools

728x90
반응형

1. itertools 모듈 소개 및 기본 개념

  • Python의 itertools 모듈은 반복자(iterators)를 처리하기 위한 도구 모음
  • 이 모듈은 일반적인 Python 내장 컨테이너(리스트, 딕셔너리 등)와는 달리 반복자를 활용하여 효율적인 데이터 처리를 가능

반복자(Iterator)란?

  • 반복자는 for 루프에서 사용될 수 있는 데이터 타입을 의미
    • EX) 리스트(list)
  • itertools 모듈은 고급 도구들을 제공
  • itertools의 함수들은 일반적으로 결과를 바로 반환하지 않고 반복자 객체(iterator)를 반환 
    • 값은 확인하려면 보통 list() 함수를 사용하여 리스트로 변환
--------------------------------------------------------------------------------

 

2. 순열, 조합, 곱셈 (Combinatoric Iterators)

  •  가장 유용하고 강력한 기능은 순열, 조합, 그리고 데카르트 곱과 같은 조합론적 함수들

2.1. product (데카르트 곱)

  • product 함수는 입력된 반복 가능 객체들의 데카르트 곱(Cartesian product)을 계산
기능
설명
데카르트 곱
모든 가능한 요소의 쌍 또는 튜플을 반환
사용법
from itertools import product를 통해 가져와 사용
결과 형태
결과는 반복자(iterator) 형태로 반환
  • EX: 리스트 A =와 B =의 데카르트 곱을 계산하면, (1, 3), (1, 4), (2, 3), (2, 4)의 순서로 결합됩니다.
  • product를 사용할 때는 반복 횟수(repeat)를 정의 가능
    • repeat=2를 설정하면 입력된 반복자를 두 번 사용하여 데카르트 곱을 계산
from itertools import product
A = [1, 2]
B = [3, 4]

prod = product(A, B)
print("product(A, B):", list(prod))
## 출력: product(A, B): [(1, 3), (1, 4), (2, 3), (2, 4)]

# repeat 사용 예: A의 2-튜플(자기 자신과의 곱)
print("product(A, repeat=2):", list(product(A, repeat=2)))
## 출력: product(A, repeat=2): [(1, 1), (1, 2), (2, 1), (2, 2)]

2.2. permutations (순열)

  • permutations 함수는 입력값의 모든 가능한 순서(ordering)를 반환
    • EX: (1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)과 같이 모든 순서가 반환
길이 지정: permutations 함수의 두 번째 인수로 순열의 길이를 지정할 수 있습니다. 예를 들어, 길이 2를 지정하면 입력 요소 중 두 개를 선택하여 가능한 모든 순서를 반환합니다.
from itertools import permutations
data = [1, 2, 3]

# 전체 길이 순열
print("permutations(data):", list(permutations(data)))
## 출력: permutations(data): [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

# 길이 2 순열
print("permutations(data, 2):", list(permutations(data, 2)))
## 출력: permutations(data, 2): [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

2.3. combinationscombinations with replacement (조합)

2.3.1. combinations

  • combinations 함수는 지정된 길이의 모든 가능한 조합 생성
  • 이 함수는 조합의 길이(length)를 두 번째 인수로 지정하는 것이 필수
  • 일반적인 조합과 마찬가지로, 이 함수는 동일한 인수의 조합(반복)이나 순서만 다른 조합(순열)을 반환 X

 

2.3.2. combinations_with_replacement

  • 반복(repetition)을 허용하는 조합
  • EX: (1, 1)과 같이 요소가 자기 자신과 조합되는 것도 허용
from itertools import combinations, combinations_with_replacement
items = [1, 2, 3]

# combinations: 순서 무시, 반복 허용 X
print("combinations(items, 2):", list(combinations(items, 2)))
## 출력: combinations(items, 2): [(1, 2), (1, 3), (2, 3)]

# combinations_with_replacement: 같은 요소 중복 허용
print("combinations_with_replacement(items, 2):", list(combinations_with_replacement(items, 2)))
## 출력: combinations_with_replacement(items, 2): [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
--------------------------------------------------------------------------------

3. 유용한 함수 (Tool Functions)

  • itertools는 단순한 조합론적 기능을 넘어 데이터를 효과적으로 처리하는 유용한 함수들도 제공

3.1. accumulate (누적)

  • accumulate 함수는 누적된 합(accumulated sums)을 반환하는 반복자를 생성
기능
설명
기본 동작
기본적으로 입력 요소들의 누적 합계를 계산
예시
리스트 의 누적 합은 1, 3, 6, 10이 됩니다 (첫 번째 요소는 동일하게 유지되고, 이후 1+2=3, 3+3=6, 6+4=10으로 계산됩니다).
이진 함수 적용
두 번째 인수로 이진 함수(func)를 입력하여 다른 연산을 수행하도록 지정 가능
다른 연산 적용 예시:
1. 누적 곱셈: operator.mul 함수를 사용하여 누적 곱셈을 수행할 수 있습니다. 1, 2, 6, 24로 변환됩니다 (1, 1*2=2, 2*3=6, 6*4=24).
2. 누적 최댓값: max 함수를 사용하면 누적 최댓값을 반환합니다. 이전 요소들과 비교하여 가장 큰 값을 유지합니다.
from itertools import accumulate
import operator

nums = [1, 2, 3, 4]

# 기본: 누적 합
print("accumulate sum:", list(accumulate(nums)))
## 출력: accumulate sum: [1, 3, 6, 10]

# 누적 곱 (operator.mul)
print("accumulate mul:", list(accumulate(nums, operator.mul)))
## 출력: accumulate mul: [1, 2, 6, 24]

# 누적 최대값 (max)
print("accumulate max:", list(accumulate([3,1,4,2], max)))
## 출력: accumulate max: [3, 3, 4, 4]
 

3.2. groupby (그룹화)

  • groupby 함수는 반복 가능한 객체에서 키(key)와 그룹을 반환하는 반복자 생성
기능
설명
입력 필요
반복 가능한 객체와 그룹화에 적용될 키(key) 함수가 필요
키 함수
키 함수는 입력 요소에 적용되어 True 또는 False를 반환하는 방식으로 그룹을 나눔
결과 반환
그룹화된 결과는 키와 group 객체(또 다른 반복자) 형태로 반환됩니다. 이 group 객체는 리스트 등으로 변환해야 내용을 확인할 수 있습니다.
예시 1: 조건 기반 그룹화 어떤 숫자가 3보다 작은지 여부를 키로 정의하면, 는 다음과 같이 그룹화될 수 있습니다:
키: True (1과 2가 3보다 작음)
키: False (3과 4가 3보다 작지 않음)
참고: 키 함수를 정의할 때 lambda 표현식을 사용하면 한 줄로 간단하게 기능을 구현 가능.
예시 2: 딕셔너리 리스트 그룹화 groupby를 사용하여 이름과 나이를 가진 딕셔너리 리스트를 나이(age)를 키로 그룹화 가능. 이 경우, 동일한 나이를 가진 요소들(TimJen이 25세로 그룹화)이 하나의 그룹으로 묶이게 됨.
 
from itertools import groupby
data = [1,1,2,2,3,1]
# 단순 예: 값 자체로 그룹화 (연속 항목 기준)
for key, grp in groupby(data):
    print(key, "->", list(grp))
## 출력:
# 1 -> [1, 1]
# 2 -> [2, 2]
# 3 -> [3]
# 1 -> [1]

# 딕셔너리 리스트를 age로 그룹화하려면 먼저 age 기준 정렬 필요
people = [
    {"name": "Tim", "age": 25},
    {"name": "Jen", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Ann", "age": 20}
]
people_sorted = sorted(people, key=lambda x: x['age'])
for age, group in groupby(people_sorted, key=lambda x: x['age']):
    print(age, ":", [p['name'] for p in group])
## 출력:
# 20 : ['Ann']
# 25 : ['Tim', 'Jen']
# 30 : ['Bob']
--------------------------------------------------------------------------------

4. 무한 반복자 (Infinite Iterators)

  • itertools는 무한히 반복되는 세 가지 함수를 제공합니다

4.1. count

  • count 함수는 시작 값부터 시작하여 무한히 카운트하는 반복자 생성
  • 시작 값을 지정할 수 있으며, 지정된 시작 값부터 매 반복마다 1씩 증가 (예: 10, 11, 12...).
from itertools import count, islice

# count는 시작값부터 1씩 증가하는 무한 반복자
print("count from 10 (first 5):", list(islice(count(10), 5)))
## 출력: count from 10 (first 5): [10, 11, 12, 13, 14]

 

4.2. cycle

  • cycle 함수는 입력된 반복 가능한 객체(iterable)를 인수로 받아 그 요소를 무한히 순환
  • 리스트 이 주어지면, 1, 2, 3, 1, 2, 3, ...와 같이 무한히 반복
from itertools import cycle, islice

# cycle은 iterable을 무한히 순환
items = ['A', 'B', 'C']
print("cycle items (첫 7개):", list(islice(cycle(items), 7)))
## 출력: cycle items (첫 7개): ['A', 'B', 'C', 'A', 'B', 'C', 'A']

4.3. repeat

  • repeat 함수는 특정 값을 반복
    • 기본적으로 무한 루프를 생성
    • 두 번째 인수로 반복 횟수를 지정하면 해당 횟수만큼만 반복하고 종료
from itertools import repeat, islice

# repeat은 특정 값을 반복
print("repeat 5 times:", list(islice(repeat("hi"), 5)))
## 출력: repeat 5 times: ['hi', 'hi', 'hi', 'hi', 'hi']

# repeat의 두 번째 인수로 횟수 지정 (finite 반복)
print("repeat('x', 3):", list(repeat('x', 3)))
## 출력: repeat('x', 3): ['x', 'x', 'x']

 

 

*******참고*******

 

  • 조합/순열/곱셈 관련 함수는 탐색/브루트포스나 상태 조합 생성에 유용
    • 이터레이터이므로 list()로 한꺼번에 만들면 메모리 사용이 커질 수 있음.
  • accumulate는 누적 계산(합, 곱, 최댓값 등)에 편리.
  • groupby를 쓸 때는 사전 정렬(sort) 를 꼭 진행 — 그렇지 않으면 의도한 그룹화가 되지 않습니다.
  • count, cycle, repeat 같은 무한 반복자는 islice로 잘라서 사용

 

728x90
반응형