파이썬의 defaultdict 사용법

파이썬의 defaultdict 사용법

Python
파이썬의 defaultdict 사용법
Author

gabriel yang

Published

October 2, 2024


파이썬의 defaultdict는 표준 라이브러리인 collections 모듈에서 제공하는 특별한 딕셔너리 유형입니다. 일반적인 딕셔너리와 유사하게 동작하지만, 기본값을 자동으로 제공하여 키가 없을 때 발생하는 오류를 방지하고, 반복적으로 값을 처리할 때 코드의 간결성을 높여줍니다.

이번 글에서는 defaultdict를 사용하는 이유와 그 사용 방법을 예시 코드와 함께 설명하겠습니다.

1. 왜 defaultdict를 사용하는가?

기본적으로 파이썬의 딕셔너리에서 존재하지 않는 키를 조회하면 KeyError가 발생합니다. 이 문제를 해결하기 위해 일반적인 딕셔너리에서는 조건문으로 키가 존재하는지 확인하거나, get() 메서드를 사용하여 기본값을 반환하는 방식이 필요합니다.

하지만, defaultdict를 사용하면 키가 없을 때 자동으로 기본값을 할당해주기 때문에 이러한 처리가 불필요해집니다. defaultdict는 특히 리스트, , 카운터와 같이 기본값을 많이 다루는 상황에서 매우 유용합니다.

2. defaultdict 사용 방법

defaultdict는 기본값을 자동으로 생성하는 함수나 클래스와 함께 사용됩니다. defaultdict를 생성할 때, 기본값을 반환할 함수를 인자로 제공하면 됩니다. 이 함수는 키가 존재하지 않을 때 호출되어 해당 키의 기본값을 생성해줍니다.

기본 문법

from collections import defaultdict

# 기본값 생성 함수를 인자로 받음
my_defaultdict = defaultdict(default_factory)
  • default_factory: 새로운 키가 추가될 때 호출되어 해당 키의 기본값을 생성하는 함수입니다.

3. defaultdict 사용 예시

예시 1: 리스트를 기본값으로 사용

defaultdict의 가장 흔한 사용 예시는 리스트를 기본값으로 사용하는 경우입니다. 예를 들어, 여러 키에 대해 값을 리스트에 추가하고 싶을 때, 키가 존재하지 않는다면 빈 리스트를 자동으로 생성해줍니다.

from collections import defaultdict

# 리스트를 기본값으로 설정
list_dict = defaultdict(list)

# 키가 존재하지 않으면 빈 리스트가 자동으로 생성됨
list_dict['fruits'].append('apple')
list_dict['fruits'].append('banana')
list_dict['vegetables'].append('carrot')

print(list_dict)

출력:

defaultdict(<class 'list'>, {'fruits': ['apple', 'banana'], 'vegetables': ['carrot']})

이 예시에서는 list_dict에서 'fruits''vegetables'라는 키가 처음 사용될 때 빈 리스트가 자동으로 생성되고, 값을 추가할 수 있습니다.

예시 2: 기본값을 0으로 설정해 카운팅하기

숫자를 카운팅할 때는 정수형 0을 기본값으로 설정하는 경우가 많습니다. 이를 통해 키가 없을 때 자동으로 0부터 시작하여 값을 증가시킬 수 있습니다.

from collections import defaultdict

# 0을 기본값으로 설정해 카운터 역할 수행
count_dict = defaultdict(int)

words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']

for word in words:
    count_dict[word] += 1

print(count_dict)

출력:

defaultdict(<class 'int'>, {'apple': 3, 'banana': 2, 'orange': 1})

이 코드는 각 단어의 등장 횟수를 카운팅합니다. 'apple', 'banana', 'orange' 키가 처음 등장할 때 기본값으로 0이 설정된 후, 값을 증가시켜 카운팅 작업을 수행합니다.

예시 3: 셋을 기본값으로 사용해 중복된 항목 제거

셋(set)은 중복된 값을 허용하지 않는 자료형입니다. defaultdict에 셋을 기본값으로 사용하면, 키에 대해 고유한 값을 관리하는 딕셔너리를 쉽게 만들 수 있습니다.

from collections import defaultdict

# 셋을 기본값으로 설정
set_dict = defaultdict(set)

set_dict['colors'].add('red')
set_dict['colors'].add('blue')
set_dict['colors'].add('red')  # 중복된 값 추가 시 무시됨
set_dict['fruits'].add('apple')

print(set_dict)

출력:

defaultdict(<class 'set'>, {'colors': {'red', 'blue'}, 'fruits': {'apple'}})

이 예시에서는 'colors' 키에 대해 중복된 'red' 값이 무시되었고, 각 키에 대해 고유한 값이 저장됩니다.

예시 4: 함수로 기본값 설정

defaultdict에 특정 함수나 람다 함수를 전달해 기본값을 동적으로 설정할 수도 있습니다. 예를 들어, 기본값으로 100을 반환하도록 설정할 수 있습니다.

from collections import defaultdict

# 기본값을 100으로 설정하는 함수
default_dict = defaultdict(lambda: 100)

print(default_dict['score'])  # 키가 없으면 기본값 100이 반환됨
print(default_dict['age'])    # 또 다른 기본값 100이 반환됨

출력:

100
100

여기서는 'score''age' 키가 처음 조회될 때 lambda 함수를 통해 기본값 100이 자동으로 할당됩니다.

4. defaultdict vs 일반 딕셔너리

defaultdict는 일반 딕셔너리와 다르게 키가 없을 때 자동으로 기본값을 생성한다는 점에서 차이가 있습니다. 아래는 두 자료형의 차이점입니다.

  • 일반 딕셔너리: 키가 없을 때 KeyError를 발생시킴.
  • defaultdict: 키가 없을 때 지정된 기본값을 자동으로 생성하여 오류 없이 처리.

일반 딕셔너리로도 비슷한 처리가 가능하지만, 조건문이나 setdefault() 메서드를 통해 처리해야 하므로 코드가 복잡해집니다. 반면, defaultdict는 이를 간결하게 처리할 수 있습니다.

예시: 일반 딕셔너리로 처리한 경우

# 일반 딕셔너리 사용 시
my_dict = {}

# 키가 없으면 기본값을 설정해야 함
if 'fruits' not in my_dict:
    my_dict['fruits'] = []
my_dict['fruits'].append('apple')

print(my_dict)

위 코드에서는 딕셔너리에 'fruits' 키가 없는 경우를 따로 처리해야 합니다. 하지만 defaultdict를 사용하면 이러한 조건문을 없앨 수 있습니다.

5. defaultdict의 사용 시 주의점

defaultdict는 편리하지만 몇 가지 주의할 점이 있습니다.

  • 기본값 자동 생성: 키가 존재하지 않을 때 자동으로 기본값을 생성하므로, 의도치 않게 키가 추가되는 경우가 있을 수 있습니다. 기본값을 생성할 필요가 없는 경우는 일반 딕셔너리를 사용하는 것이 더 적합합니다.

  • 기본값 호출 방식: defaultdict는 기본값을 생성할 때마다 default_factory를 호출합니다. 따라서 기본값이 복잡한 객체이거나 값 생성 비용이 클 경우, 이를 염두에 두고 사용해야 합니다.

결론

defaultdict는 파이썬에서 매우 유용한 자료형으로, 키가 없을 때 발생하는 오류를 방지하고 자동으로 기본값을 생성하여 코드의 간결성과 효율성을 높여줍니다. 특히 리스트, 셋, 숫자 카운팅과 같은 작업에서 매우 유용하게 사용됩니다.

defaultdict를 사용하면 키가 없는 상황을 처리하는 복잡한 코드를 줄일 수 있어, 보다 간결하고 직관적인 파이썬 코드를 작성할 수 있습니다. 언제든지 기본값이 필요하거나 반복적으로 값을 추가해야 하는 상황에서는 defaultdict를 활용해보세요!