-
유사 딕셔너리 defaultdict() 활용법Engineering WIKI/Python 2022. 5. 19. 11:31
defaultdict()는 딕셔너리를 만드는 dict클래스의 서브클래스이다.
작동하는 방식은 거의 동일한데, defaultdict()는 인자로 주어진 객체(default-factory)의 기본값을 딕셔너리값의 초깃값으로 지정할 수 있다.
숫자, 리스트, 셋등으로 초기화 할 수 있기때문에 여러 용도로 사용할 수 있다.
기본적인 작동방식을 살펴보면
from collections import defaultdict # 외부함수이기 때문에 import 해야한다. int_dict = defaultdict(int) print(int_dict) # defaultdict(<class 'int'>, {}) # 디폴트값이 int인 딕셔너리
위와 같이 설정을 하면 값을 지정하지 않은 키는 그 값이 0으로 지정된다.
int_dict['key1'] # 0 print(int_dict) # defaultdict(<class 'int'>, {'key1': 0})
키에 명시적으로 값을 지정하게 되면 그 값이 지정된다.
int_dict['key2'] = 'test' print(int_dict) # defaultdict(<class 'int'>, {'key1': 0, 'key2': 'test'})
defaultdict라는 말 그대로 처음 키를 지정할 때 값을 주지 않으면 해당 키에 대한 값을 디폴트 값을 지정하겠다는 뜻이다.
리스트, 셋을 디폴트 값으로 지정해 보자.
default 값으로 list를 줬을때 작동방식
list_dict = defaultdict(list) print(list_dict) #defaultdict(<class 'list'>, {}) # 디폴트값이 list인 딕셔너리 print(list_dict['key1']) # 값을 지정하지 않으면 빈 리스트로 초기화. [] list_dict['key2'] = 'test' # 값을 지정하면 해당값으로 초기화 print(list_dict) # defaultdict(<class 'list'>, {'key1': [], 'key2': 'test'})
default 값으로 set을 줬을때 작동방식
set_dict = defaultdict(set) print(set_dict) # defaultdict(<class 'set'>, {}) # 디폴트값이 set인 딕셔너리 set_dict['key1'] # 값을 지정하지 않으면 빈 리스트로 초기화. set() set_dict['key2'] = 'test' # 값을 지정하면 해당값으로 초기화 print(set_dict) # defaultdict(<class 'set'>, {'key1': set(), 'key2': 'test'})
자 그러면 언제 defaultdict()를 사용하는것이 좋을까?
키의 개수를 세야하는 상황이나, 리스트나 셋의 항목을 정리해야 하는 상황에 적절할것 같다.
레퍼런스에서도 그런예제들이 보통이다.
문자열에 나타난 알파벳의 횟수를 계산하는 방법을 살펴보자.
default(int) 활용예제
letters = 'dongdongfather' letters_dict = defaultdict(int) for k in letters: letters_dict[k] += 1 #키에 대한 값이 없으면 값을 0으로 초기화 print(letters_dict) # defaultdict(<class 'int'>, {'d': 2, 'o': 2, 'n': 2, 'g': 2, 'f': 1, 'a': 1, 't': 1, 'h': 1, 'e': 1, 'r': 1})
딕셔너리에 키가 있는지(해당 알파벳) 확인 절차를 거칠 필요없이 바로 값을 1증가시켜주면 된다.
없으면 그 키를 만들어주고 초깃값을 0으로 세팅해 주기 때문이다.
비교를 위해 defaultdict()를 사용하지 않은 방법을 보면
defaultdict()를 사용하지 않을때
letters = 'dongdongfather' letters_dict = {} for k in letters: if not k in letters_dict: # 키가 있는지 확인 letters_dict[k] = 0 # 없으면 0으로 초깃값 할당 letters_dict[k] += 1 print(letters_dict) # {'d': 2, 'o': 2, 'n': 2, 'g': 2, 'f': 1, 'a': 1, 't': 1, 'h': 1, 'e': 1, 'r': 1}
위와 같이 키가 존재하는지 검사하는 코드와 0으로 초기화하는 코드가 추가로 필요하다.
리스트나 셋을 이용해서 여러개의 값을 합쳐야 할때도 쉽게 처리할 수 있다.
다음 예제에서 내가 하고 싶은것은 주어진 성과 이름 튜플에서 각 성에 대해 어떤 이름들이 있는가 분류하는것이다.
defaultdict(list) 활용예제
name_list = [('kim','sungsu'), ('kang','hodong'), ('park','jisung'), ('kim','yuna'), ('park','chanho'), ('kang','hodong')] ndict = defaultdict(list) for k, v in name_list: # 리스트의 요소가 튜플이기 때문에 k, v값으로 할당 ndict[k].append(v) # 값이 리스트이기때문에 append()를 이용해서 항목추가 print(ndict) # defaultdict(<class 'list'>, {'kim': ['sungsu', 'yuna'], 'kang': ['hodong', 'hodong'], 'park': ['jisung', 'chanho']})
이렇게 간단하게 각 성이 가진 이름을 취합할 수 있다.
위 리스트에 보면 name_list에서 'kang hodong'이 두번 나왔기때문에 딕셔너리에서도 'hodong'이 두번 출력된걸 알 수 있다.
보통 이런 중복자료는 의미가 없기때문에 없애주고 싶다.
이럴때 set을 기본값으로 주면 바로 해결된다.
set은 중복값을 허용하지 않기 때문이다.
defaultdict(set) 활용예제
name_list = [('kim','sungsu'), ('kang','hodong'), ('park','jisung'), ('kim','yuna'), ('park','chanho'), ('kang','hodong')] nset = defaultdict(set) # 초깃값을 셋으로 설정 for k, v in name_list: ndict[k].add(v) # list는 append()를 사용해서 항목추가. set은 add()를 사용해서 항목추가 print(ndict) # defaultdict(<class 'set'>, {'kim': {'sungsu', 'yuna'}, 'kang': {'hodong'}, 'park': {'jisung', 'chanho'}})
'Engineering WIKI > Python' 카테고리의 다른 글
파이썬 퀵 정렬 (0) 2022.05.25 Python3 vs Pypy3 (0) 2022.05.25 Python TDD (0) 2022.05.23 파이썬 상속 (Inheritance) (0) 2022.05.23 문자열 split() 과 split(" ") 차이 (0) 2022.05.19 함수 주석 (0) 2022.05.17 any, all 함수 (0) 2022.05.17 operator의 itemgetter를 사용해서 리스트 정렬 (0) 2022.05.17