파이썬 collections 모듈의 핵심 컨테이너 타입 활용법

파이썬 데이터 구조 최적화: collections 모듈

파이썬 표준 라이브러리 내 collections 모듈은 범용 자료형인 리스트, 튜플, 딕셔너리를 보완하는 특화된 컨테이너 도구들을 제공합니다. 복잡한 로직을 간소화하고 메모리 효율성을 높이기 위해 자주 활용되며, 주요 구성 요소는 다음과 같습니다.

  • 빈도 수 계산용 Counter
  • 이중 끝에서 조작 가능한 deque
  • 초기값 자동 할당 defaultdict
  • 순서가 보장되는 OrderedDict
  • 명칭 부여 튜플 namedtuple

1. Counter: 객체 빈도 통계

Counter 클래스는 해시 테이블 기반의 서브클래스로, iterable 한 데이터의 요소별 출현 횟수를 자동으로 집계합니다. 결과는 딕셔너리 형태로 반환되지만, 더 직관적인 연산 방법을 지원합니다.

주요 메서드 설명

  • most_common(n): 요소 등장 횟수에 따라 내림차순 정렬하여 상위 n 개 원소를 튜플 쌍의 리스트로 반환합니다.
  • elements(): 카운트된 결과를 기준으로 각 요소를 실제 개수만큼 반복 출력하는 이터레이터를 생성합니다.
  • update(): 현재 카운터에 다른 데이터를 병합하거나 값을 증가시킵니다.
  • subtract(): 다른 카운터나 컬렉션에서 현재 카운터의 값을 차감하는 연산을 수행합니다.

구현 예제

from collections import Counter

# 문자열 및 리스트 형태의 입력 데이터 정의
sample_text = "abcbcaccbbad"
char_sequence = ["a","b","c","a","b","b"]
mapping_data = {"x":3, "y":2, "z":2}

# 다양한 자료형으로 Counter 인스턴스 생성
freq_counter_str = Counter(sample_text)
freq_counter_li = Counter(char_sequence)
freq_counter_dict = Counter(mapping_data)

# 가장 많이 등장한 상위 2 개의 요소 추출
top_elements = freq_counter_str.most_common(2)
print(f"상위 2 빈도: {top_elements}")

# elements() 를 통해 확장된 시퀀스 확인
expanded_view = "".join(sorted(freq_counter_str.elements()))
print(f"확장된 문자열: {expanded_view}")

# 값 업데이트 동작
freq_counter_str.update("sas1")

2. deque: 양방향 우선순위 큐

리스트보다 양쪽 끝에 요소를 추가하거나 제거할 때(O(1)) 훨씬 높은 성능을 보이는 선형 자료구조입니다. 스택(Stack) 또는 큐(Queue) 구현에 적합하며, 회전 이동 등 유연한 조작이 가능합니다.

  • append / appendleft: 오른쪽 혹은 왼쪽 끝으로 요소 삽입
  • pop / popleft: 오른쪽 혹은 왼쪽 끝에서 요소 추출 및 제거
  • rotate(n): 전체 요소를 지정된 횟수만큼 순환 이동
  • remove(value): 특정 값을 가진 첫 번째 요소를 제거
  • reverse: 모든 요소 순서를 반전

3. defaultdict: 누락된 키 자동 처리

일반 딕셔너리와 달리 존재하지 않는 키를 접근했을 때 KeyError 가 발생하지 않고, 초기화 시 지정한 공백 값으로 자동으로 생성하여 반환합니다. 이는 중첩된 구조나 집계 작업에서 코드를 간결하게 만드는 데 유용합니다.

from collections import defaultdict

# 값을 리스트 형태로 자동 생성하도록 설정
grouped_data = defaultdict(list)

# 키가 없어도 바로 값에 접근 가능 (자동으로 빈 리스트 생성 후 extend/update 가능)
grouped_data["category_A"].extend([1, 2, 3])
grouped_data["category_B"].append({"status": "active"})

print(grouped_data)

4. OrderedDict: 삽입 순서 보존

표준 딕셔너리는 최근 버전의 파이썬부터 삽입 순서를 보장하지만, OrderedDict 는 명시적으로 순서의 의미와 비교 연산에서의 순서 의존성을 지원합니다. 특히 이전 버전 호환성이나 순서 이동 기능이 필요한 경우 유용합니다.

순서 유지 효과 비교

일반 딕셔너리에 비해 키의 등록 순서에 따른 출력 보장이 명확합니다.

from collections import OrderedDict

# 일반 딕셔너리 사용 시에도 순서보장되나 의도는 명확하지 않을 수 있음
standard_map = {}
standard_map['first'] = 1
standard_map['second'] = 2

# OrderedDict 사용 시 의도적 순서 강조
ordered_map = OrderedDict()
ordered_map['first'] = 1
ordered_map['second'] = 2

# 순서대로 항목 순회
for key, value in ordered_map.items():
    print(f"{key}: {value}")

5. namedtuple: 불변 필드 객체

튜플의 가볍고 불변하는 특성에 필드명을 부여하여 속성 접근을 용이하게 하는 클래스를 동적으로 생성합니다. namedtuple('ClassName', 'field1, field2') 형식을 사용합니다.

잘못된 필드명 처리 (rename 매개변수)

필드명으로 파이썬 키워드 (예: class) 나 중복 이름을 사용할 경우 오류가 발생합니다. 이때 rename=True 옵션을 적용하면 내부적으로 유효한 이름 (_0, _1 등) 으로 자동 치환됩니다.

from collections import namedtuple

# 정의
Profile = namedtuple('Profile', ['id', 'user_name', 'rank'])

# 인스턴스 생성 및 접근
user_01 = Profile(1001, "jinho", "VIP")
print(user_01.user_name)

# 잘못된 필드명 테스트 및 자동 수정
try:
    # 'class' 는 예약어이므로 충돌 발생 예상
    InvalidStruct = namedtuple('Item', 'name, type, class, color')
except ValueError:
    print("키워드 충돌로 정의 불가")

# rename=True 를 통한 해결
FixedStruct = namedtuple('Item', 'name, type, class, color', rename=True)
item_obj = FixedStruct("A", "Type1", "C1", "Red")
print(FixedStruct._fields) # ('name', 'type', '_2', 'color')

태그: python collections-module data-structures standard-library

5월 22일 02:35에 게시됨