🎯 1. Counter ⭐⭐⭐

기본 사용법

from collections import Counter

# 리스트 카운팅
arr = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
counter = Counter(arr)
print(counter)
# Counter({4: 4, 3: 3, 2: 2, 1: 1})

# 문자열 카운팅
s = "hello world"
counter = Counter(s)
print(counter)
# Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})

# 단어 카운팅
words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
counter = Counter(words)
# Counter({'apple': 3, 'banana': 2, 'cherry': 1})

딕셔너리처럼 사용

counter = Counter(['a', 'b', 'c', 'a', 'b', 'a'])

# 특정 키의 개수
counter['a']            # 3
counter['z']            # 0 (없어도 에러 안 남!)

# 업데이트
counter['a'] += 1       # Counter({'a': 4, 'b': 2, 'c': 1})
counter.update(['a', 'd', 'd'])
# Counter({'a': 5, 'b': 2, 'd': 2, 'c': 1})

# 삭제
del counter['c']        # Counter({'a': 5, 'b': 2, 'd': 2})

most_common() - 가장 많은 것 찾기 ⭐⭐⭐

counter = Counter(['a', 'b', 'c', 'a', 'b', 'a'])

# 가장 많은 n개
counter.most_common(2)  # [('a', 3), ('b', 2)]
counter.most_common(1)  # [('a', 3)]
counter.most_common()   # [('a', 3), ('b', 2), ('c', 1)] (전체)

# 가장 많은 것의 개수
most_common_elem, count = counter.most_common(1)[0]
# most_common_elem = 'a', count = 3

# 가장 적은 것 찾기
counter.most_common()[-1]  # ('c', 1)

Counter 산술 연산 ⭐⭐⭐

c1 = Counter(['a', 'b', 'c', 'a'])
c2 = Counter(['a', 'b', 'd', 'd'])

# 덧셈 (합치기)
c1 + c2
# Counter({'a': 3, 'b': 2, 'd': 2, 'c': 1})

# 뺄셈 (차집합)
c1 - c2
# Counter({'a': 1, 'c': 1})  # c1에만 있거나 더 많은 것

c2 - c1
# Counter({'d': 2})  # c2에만 있거나 더 많은 것

# 교집합 (최솟값)
c1 & c2
# Counter({'a': 1, 'b': 1})

# 합집합 (최댓값)
c1 | c2
# Counter({'a': 2, 'd': 2, 'b': 1, 'c': 1})

elements() - 원소 나열

counter = Counter(a=3, b=2, c=1)

# 원소를 개수만큼 반복
list(counter.elements())
# ['a', 'a', 'a', 'b', 'b', 'c']

# 정렬된 형태로
sorted(counter.elements())
# ['a', 'a', 'a', 'b', 'b', 'c']

코테 실전 패턴

# 패턴 1: 가장 많이 등장하는 문자
s = "hello world"
counter = Counter(s)
most_common_char = counter.most_common(1)[0][0]  # 'l'

# 패턴 2: 등장 횟수가 1인 것만
counter = Counter([1, 2, 2, 3, 3, 3, 4])
unique = [k for k, v in counter.items() if v == 1]
# [1, 4]

# 패턴 3: 두 리스트의 공통 원소와 개수
arr1 = [1, 2, 2, 3, 3, 3]
arr2 = [2, 2, 3, 4, 4]
c1, c2 = Counter(arr1), Counter(arr2)
common = c1 & c2
# Counter({2: 2, 3: 1})

# 패턴 4: 완주하지 못한 선수 (프로그래머스)
def solution(participant, completion):
    answer = list((Counter(participant) - Counter(completion)).keys())[0]
    return answer

🎯 2. defaultdict - 기본값이 있는 딕셔너리 ⭐⭐⭐

기본 사용법

from collections import defaultdict

# int 기본값 (0)
d = defaultdict(int)
d['a'] += 1             # KeyError 없이 바로 사용!
d['b'] += 5
print(d)
# defaultdict(<class 'int'>, {'a': 1, 'b': 5})

# list 기본값 ([])
d = defaultdict(list)
d['fruits'].append('apple')
d['fruits'].append('banana')
d['veggies'].append('carrot')
print(d)
# defaultdict(<class 'list'>, {'fruits': ['apple', 'banana'], 'veggies': ['carrot']})

# set 기본값 (set())
d = defaultdict(set)
d['numbers'].add(1)
d['numbers'].add(2)
d['numbers'].add(1)  # 중복 무시
print(d)
# defaultdict(<class 'set'>, {'numbers': {1, 2}})

타입별 기본값

from collections import defaultdict

# int: 0
d = defaultdict(int)
print(d['key'])         # 0

# list: []
d = defaultdict(list)
print(d['key'])         # []

# set: set()
d = defaultdict(set)
print(d['key'])         # set()

# str: ''
d = defaultdict(str)
print(d['key'])         # ''

# float: 0.0
d = defaultdict(float)
print(d['key'])         # 0.0