개요
Python으로 딕셔너리를 사용하다 보면 키에 대한 값이 없을 때를 처리해야 하는 경우가 발생할 수 있다. 내 경우에는 보통 아래와 같이 처리해 오는 편이었다.
def count_letters(word):
counter = {}
for letter in word:
if letter not in counter:
counter[letter] = 0
else:
counter[letter] += 1
return counter
예시 코드의 경우에는 0이 일종의 기본값인 셈인데, 만약 딕셔너리에 기본값을 설정하면 불필요한 조건문을 제거함으로써 보다 가독성 있는 코드가 될 수 있을 것 같다.
따라서 이번 글에서는 딕셔너리에 기본값을 설정하는 방법 중 하나인 defaultdict에 대해서 알아보려고 한다.
defaultdict
defaultdict은 dict 클래스의 하위 클래스로, 생성자의 인자로 주어진 객체(default-factory)의 기본값을 딕셔너리의 초기값을 지정한다. 그 외에는 일반적인 딕셔너리와 동일하다. default-factory로는 기본값을 생성하는 함수를 전달할 수도 있다.
기본적인 사용은 다음과 같다.
from collections import defaultdict
def count_letters(word):
counter = defaultdict(int)
for letter in word:
counter[letter] += 1
return counter
default-factory에 int를 전달하면 기본값은 0이 되고, list를 전달하면 기본값은 빈 리스트가 된다.
예시 - 카테고리 별 묶기
빈 리스트를 기본값으로 하는 defaultdict은 데이터를 특정 기준으로 묶을 때 유용하다.
아례 예시는 리스트의 각 원소의 첫 번째 값을 기준으로 데이터를 묶은 결과이다.
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
d[k].append(v)
sorted(d.items())
예시 - 람다 함수 활용
default-factory에 함수를 전달하면 사용자 정의 기본값을 사용할 수도 있다. 간단하게는 람다 함수를 활용하는 방법이 있다.
def constant_factory(value):
return lambda: value
d = defaultdict(constant_factory('<missing>'))
d.update(name='John', action='ran')
'%(name)s %(action)s to %(object)s' % d
참고 문서
https://docs.python.org/3/library/collections.html
https://www.daleseo.com/python-collections-defaultdict/