Victoree's Blog

[3] 데이터 구조체 - 딕셔너리와 집합, 카운터 본문

Python/Fluent Python

[3] 데이터 구조체 - 딕셔너리와 집합, 카운터

victoree 2023. 6. 15. 13:13
728x90

딕셔너리는 파이썬의 핵심이다. 기본적인 dict 외에 표준 라이브러리에서 defaultdict, OrderedDict, ChainMap, Counter 등의 매핑형을 제공하며 이는 모두 collections 모듈에 정의되어 있다. 
매핑 API 에서는 __missing__() 메소드는 키를 찾을 수 없을 때 발생하는 일을 정의할 수 있게 해준다. 

1.1 딕셔너리

조기 실패 철학에 따라, 존재하지 않는 k로 dictionary에 접근하면 dict는 오류를 발생시킨다. 만약 기본값을 설정하고 싶다면 다음과 같이 세팅할 수 있다. 

my_dict.setdefault(key, []).append(new_value)

if key not in my_dict:
	my_dict[key]=[]
my_dict[key].append(new_value)

첫 줄의 코드와 아래 3줄의 코드는 같은 역할을 수행한다. 다만 위 코드는 키를 두번 검색(키가 없을 시 3번 검색) 하지만, setdafault는 단 한번의 검색으로 모든 과정을 처리한다. 

key가 없을 때, 임의로 원하는 작업을 하고 싶다면 dict 클래스를 상속받고 __missing__() 메서드를 정의하면, KeyError 대신 원하는 작업을 수행할 수 있다. 

dict는 내부적으로 해시 테이블을 사용하고 있고, 해시가 제대로 작동하려면 빈 공간이 충분해야 하므로 공간효율성이 높지 않다. 따라서 dict를 튜플로 교체하면, 레코드 마다 하나의 해시 테이블을 가져야하는 부담과 레코드마다 필드명을 다시 저장해야하는 부담을 제거함으로 메모리 사용량을 줄일 수 있다. 

또한 dict에 항목을 추가할 때마다 파이썬 인터프리터는 해당 딕셔너리의 해시 테이블 크기를 늘릴지 판단하기 때문에, 처음부터 끝까지 dictionary를 검색하며 필요한 항목은 별도의 dictionary에 추가하고 이 별도의 dictionary를 한번에 기존 dict에 업데이트하는 것이 더 효율적이다. 

1.2 Counter

카운터는 해시 가능한 객체나 한 항목이 여러 번 들어갈 수 있는 다중 집합에서의 객체의 수를 세기위해 사용할 수 있다. Counter 클래스는 합계를 구하기 위한 +와 - 연산자를 구현하며 n개의 가장 널리 사용된 항목과 그들의 가운터로 구성된 튜플의 리스트를 반환하는 most_common([n]) 메소드를 제공한다. 

>>> ct = collections.Counter('abracadarbra')
>>> ct
Counter({'a': 5, 'r': 3, 'b': 2, 'c': 1, 'd': 1})
>>> ct.update('dfabaaaa')
Counter({'a': 10, 'b': 3, 'r': 3, 'd': 2, 'c': 1, 'f': 1})
>>> ct.most_common(2)
[('a', 10), ('b', 3)]
728x90
Comments