[Python] 초급 개념19 - collections 모듈 활용
파이썬의 collections 모듈은 기본 데이터 구조보다 더욱 효율적인 컨테이너 자료형을 제공합니다. 주요 컨테이너로는 요소 개수를 쉽게 셀 수 있는 Counter, 기본값을 자동으로 설정하는 defaultdict, 빠른 삽입과 삭제가 가능한 deque, 필드명을 지원하는 namedtuple, 순서를 유지하는 OrderedDict, 여러 딕셔너리를 하나로 묶는 ChainMap 등이 있습니다. 이러한 도구들은 코드의 가독성을 높이고, 보다 최적화된 데이터 구조를 구현하는 데 유용합니다.
🔹 1. Counter - 요소 개수 세기
Counter는 리스트, 문자열 등의 요소 개수를 쉽게 셀 수 있는 자료구조입니다. 내부적으로는 딕셔너리 형태로 데이터를 저장하며, 각 요소를 키로, 개수를 값으로 설정하여 자동으로 개수를 계산합니다.
✅ 예제 1: 리스트에서 요소 개수 세기
from collections import Counter
fruits = ["사과", "바나나", "사과", "오렌지", "바나나", "사과"]
fruit_count = Counter(fruits)
print(fruit_count)
출력 예시:
Counter({'사과': 3, '바나나': 2, '오렌지': 1})
📌 설명:
- Counter(fruits)는 리스트 내 각 요소의 개수를 자동으로 계산합니다.
- Counter 객체는 사전(dict)과 비슷한 구조로, 각 요소와 그 개수를 저장합니다.
🔹 2. defaultdict - 기본값을 지정하는 딕셔너리
defaultdict는 존재하지 않는 키를 조회할 때 기본값을 자동으로 설정할 수 있습니다. 일반적인 dict에서는 존재하지 않는 키를 조회하면 KeyError가 발생하지만, defaultdict는 미리 지정한 기본값을 반환하여 오류를 방지합니다.
✅ 예제 2: 기본값이 0인 정수형 딕셔너리
from collections import defaultdict
dd = defaultdict(int)
dd["a"] += 1
dd["b"] += 2
print(dd)
출력 예시:
defaultdict(<class 'int'>, {'a': 1, 'b': 2})
📌 설명:
- defaultdict(int)는 기본값이 0인 딕셔너리를 생성합니다.
- 존재하지 않는 키를 조회하면 자동으로 0을 반환합니다.
🔹 3. deque - 빠른 삽입과 삭제가 가능한 리스트
deque(Double-ended queue)는 양쪽에서 데이터를 추가하거나 제거할 수 있는 큐 자료구조입니다. 일반적인 리스트(list)와 비교했을 때 deque는 양쪽 끝에서의 삽입과 삭제 연산 속도가 O(1)로 매우 빠릅니다. 반면, list는 중간 삽입과 삭제는 최적화되어 있지만, 맨 앞에서 요소를 제거하는 연산이 O(n)으로 상대적으로 느립니다. 따라서, deque는 큐(queue) 또는 스택(stack)과 같은 구조가 필요한 경우 효율적인 대안이 될 수 있습니다.
✅ 예제 3: deque 활용하기
from collections import deque
dq = deque([1, 2, 3])
dq.append(4) # 오른쪽 추가
dq.appendleft(0) # 왼쪽 추가
print(dq)
출력 예시:
deque([0, 1, 2, 3, 4])
📌 설명:
- append()는 오른쪽에, appendleft()는 왼쪽에 요소를 추가합니다.
- 일반적인 리스트보다 삽입, 삭제 연산이 빠릅니다.
🔹 4. namedtuple - 가독성 높은 튜플 구조체
namedtuple은 튜플처럼 사용하면서도, 필드명을 지정하여 가독성을 높일 수 있습니다.
✅ 예제 4: namedtuple 사용하기
from collections import namedtuple
Person = namedtuple("Person", ["name", "age"])
p = Person(name="철수", age=30)
print(p.name, p.age)
출력 예시:
철수 30
📌 설명:
- namedtuple("Person", ["name", "age"])을 사용하면 필드명을 지정할 수 있습니다.
- 일반 튜플보다 직관적으로 데이터를 접근할 수 있습니다.
🔹 5. OrderedDict - 순서를 유지하는 딕셔너리
파이썬 3.7 이상에서는 일반 dict도 순서를 유지하지만, OrderedDict는 순서를 보장하는 딕셔너리를 명확히 지정할 때 사용됩니다.
✅ 예제 5: OrderedDict 활용하기
from collections import OrderedDict
ordered_dict = OrderedDict()
ordered_dict["a"] = 1
ordered_dict["b"] = 2
ordered_dict["c"] = 3
print(ordered_dict)
출력 예시:
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
📌 설명:
- OrderedDict는 입력한 순서를 유지하며, 삽입된 순서대로 항목을 저장하고 유지합니다. 파이썬 3.7 이상에서는 기본 dict도 삽입 순서를 보장하지만, OrderedDict는 순서를 명확히 유지해야 하는 경우(예: 항목의 순서 변경이 필요한 작업) 더욱 유용하게 사용할 수 있습니다.
- 기본 dict와 동일한 동작을 하지만, 순서가 중요한 경우 명시적으로 사용할 수 있습니다.
🔹 6. ChainMap - 여러 개의 딕셔너리 묶기
ChainMap은 여러 개의 딕셔너리를 하나로 합쳐서 다룰 수 있도록 합니다.
✅ 예제 6: ChainMap 활용하기
from collections import ChainMap
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
cm = ChainMap(dict1, dict2)
print(cm["b"]) # dict1의 값 우선
출력 예시:
2
📌 설명:
- ChainMap(dict1, dict2)는 두 개의 딕셔너리를 묶어서 하나처럼 사용합니다.
- 같은 키가 존재하면 앞쪽 딕셔너리 값이 우선됩니다.