본문 바로가기
Category/Python

Python의 collections 모듈 사용하기

by Corinee 2024. 11. 20.
728x90
반응형

Python의 collections 모듈은 고급 데이터 구조를 제공하는 표준 라이브러리로, 기본적으로 제공되는 데이터 구조(리스트, 튜플, 딕셔너리 등)를 보완하여 더 효율적이고 직관적인 코딩을 가능하게 해줍니다.

주요 클래스와 사용법

1. Counter

  • 용도: 요소의 개수를 자동으로 세는 해시 테이블 자료구조입니다.
  • 주요 메서드:
    • elements(): 요소를 순회(iterable) 형태로 반환.
    • most_common(n): 가장 많이 등장한 요소 상위 n개 반환.
    • subtract(): 요소의 개수를 감소시킴.
from collections import Counter

# 예제: 요소의 빈도 계산
data = ['a', 'b', 'c', 'a', 'b', 'a']
counter = Counter(data)
print(counter)  # Counter({'a': 3, 'b': 2, 'c': 1})

# 가장 많이 등장한 요소
print(counter.most_common(1))  # [('a', 3)]

# elements() 메서드
print(list(counter.elements()))  # ['a', 'a', 'a', 'b', 'b', 'c']

2. defaultdict

  • 용도: 키가 없을 때 기본값을 설정해주는 딕셔너리.
  • 주요 특징:
    • 기본값을 자동으로 생성.
    • 키가 없는 경우 KeyError를 방지.
from collections import defaultdict

# 기본값이 int (0)인 딕셔너리 생성
dd = defaultdict(int)
dd['a'] += 1
print(dd)  # defaultdict(<class 'int'>, {'a': 1})

# 기본값이 리스트인 딕셔너리 생성
dd_list = defaultdict(list)
dd_list['a'].append(1)
print(dd_list)  # defaultdict(<class 'list'>, {'a': [1]})

3. deque

  • 용도: 양방향 큐로, 리스트보다 빠르게 양쪽 끝에서 데이터를 추가하거나 제거할 수 있음.
  • 주요 메서드:
    • append(x), appendleft(x): 요소를 오른쪽 또는 왼쪽에 추가.
    • pop(), popleft(): 요소를 오른쪽 또는 왼쪽에서 제거.
    • rotate(n): 덱을 n만큼 회전.
from collections import deque

# 덱 생성
dq = deque([1, 2, 3])
dq.append(4)  # 오른쪽에 추가
dq.appendleft(0)  # 왼쪽에 추가
print(dq)  # deque([0, 1, 2, 3, 4])

# 요소 제거
dq.pop()  # 4 제거
dq.popleft()  # 0 제거
print(dq)  # deque([1, 2, 3])

# 회전
dq.rotate(1)  # 오른쪽으로 1칸 회전
print(dq)  # deque([3, 1, 2])

4. namedtuple

  • 용도: 키로 접근 가능한 튜플을 생성.
  • 특징:
    • 불변(immutable) 데이터 구조.
    • 요소에 이름으로 접근 가능.
from collections import namedtuple

# namedtuple 정의
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)

# 접근 방법
print(p.x, p.y)  # 10, 20
print(p[0], p[1])  # 10, 20

5. OrderedDict

  • 용도: 삽입 순서를 유지하는 딕셔너리(파이썬 3.7 이상에서는 기본 딕셔너리도 삽입 순서를 유지).
  • 특징:
    • 기존 dict와 달리 삽입 순서를 기억.
    • move_to_end(key, last=True): 키를 맨 앞으로 또는 맨 뒤로 이동.
from collections import OrderedDict

# OrderedDict 생성
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3

# 삽입 순서 유지
print(od)  # OrderedDict([('a', 1), ('b', 2), ('c', 3)])

# 요소 순서 변경
od.move_to_end('b')
print(od)  # OrderedDict([('a', 1), ('c', 3), ('b', 2)])

6. ChainMap

  • 용도: 여러 딕셔너리를 하나로 묶어 관리.
  • 특징:
    • 여러 딕셔너리를 병합하여 하나처럼 사용.
    • 기존 딕셔너리를 수정하면 ChainMap에 반영.
from collections import ChainMap

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
cm = ChainMap(dict1, dict2)

print(cm['a'])  # 1 (dict1에서 가져옴)
print(cm['b'])  # 2 (dict1에서 가져옴)
print(cm['c'])  # 4 (dict2에서 가져옴)

7. UserDict, UserList, UserString

  • 용도: 기본 데이터 구조를 상속받아 사용자 정의 클래스를 만들 때 사용.
  • 특징:
    • dict, list, str을 상속받는 것보다 더 안전하고 확장 가능.
    • 내부 데이터를 data 속성으로 관리.
from collections import UserDict

class MyDict(UserDict):
    def __setitem__(self, key, value):
        if isinstance(value, int):
            super().__setitem__(key, value)
        else:
            raise ValueError("Value must be an integer")

md = MyDict()
md['a'] = 10
print(md)  # {'a': 10}

collections를 사용하는 이유

  1. 효율성: 기본 데이터 구조보다 특정 작업에서 더 빠르게 동작.
  2. 가독성: 직관적이고 명확한 표현.
  3. 유연성: 다양한 자료 구조를 쉽게 확장 가능.

어떤 경우에 사용하나?

  • Counter: 요소 빈도 계산, 애너그램 문제, 데이터 분석.
  • defaultdict: 키 초기화, 그래프 문제, 빈도 계산.
  • deque: 큐, 스택, 슬라이딩 윈도우 문제.
  • namedtuple: 읽기 전용 데이터 구조 정의.
  • OrderedDict: 순서가 중요한 딕셔너리 작업.
  • ChainMap: 딕셔너리 병합 및 우선순위 관리.