키가 없는 경우의 딕셔너리를 처리하는 법인 get, setdefault 를 사용하는 법을 앞서 보았다.
visits = {
'미국': {'뉴욕', '로스엔젤레스'},
'일본': {'하코네'},
}
visits.setdefault('프랑스', set()).add('칸')
visits
{'미국': {'뉴욕', '로스엔젤레스'}, '일본': {'하코네'}, '프랑스': {'칸'}}
if (japan := visits.get('일본')) is None:
visits['일본'] = japan = set()
visits
{'미국': {'뉴욕', '로스엔젤레스'}, '일본': {'하코네'}, '프랑스': {'칸'}}
if (japan := visits.get('한국')) is None:
visits['한국'] = japan = set()
visits
{'미국': {'뉴욕', '로스엔젤레스'}, '일본': {'하코네'}, '프랑스': {'칸'}, '한국': set()}
직접 딕셔너리 생성을 제어할 수 있다면 어떨까?
class Visits:
def __init__(self):
self.data = {}
def add(self, country, city):
city_set = self.data.setdefault(country, set())
city_set.add(city)
setdefault 호출의 복잡도를 감춰주며 더 나은 인터페이스를 제공한다
visits = Visits()
visits.add('러시아', '예카테린부르크')
visits.add('탄자니아', '잔지바르')
print(visits.data)
{'러시아': {'예카테린부르크'}, '탄자니아': {'잔지바르'}}
하지만 Visits.add는 이상적이지 않으므로 collections 내장 모듈에 존재하는 defaultdict을 사용해보자
이는 클래스에 키가 없을 때 자동으로 디폴트 값을 저장한다
from collections import defaultdict
class Visits:
def __init__(self):
self.data = defaultdict(set)
def add(self, country, city):
self.data[country].add(city)
visits = Visits()
visits.add('영국', '바스')
visits.add('영국', '런던')
print(visits.data)
defaultdict(<class 'set'>, {'영국': {'런던', '바스'}})