본문 바로가기
Python

[Python] 딕셔너리 모듈

by 방준이 2020. 12. 31.
반응형

[Python] 딕셔너리 모듈

 

딕셔너리와 관련된 특수한 컨테이너 자료형인 defaultdict, Counter, OrderedDict에 대해 알아보자. 추가로 딕셔너리의 내장 함수인 setdefault() 함수에 대해서도 알아보자.

 

 

dict = {'a' : 1, 'b' : 2, 'c': 3}
dict
---------------------------------
{'a': 1, 'b': 2, 'c': 3}


dict['c'] += 1
dict['d'] += 1

## 해당 키가 존재 하지 않으면 예외가 발생한다.
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-2-56a4ceb46479> in <module>
      1 dict['c'] += 1
----> 2 dict['d'] += 1
      3 
      4 ## 해당 키가 존재 하지 않으면 예외가 발생한다.

KeyError: 'd'

 

예외가 발생하는 경우라면 다음과 같이 조건문을 이용해야 한다.

 

s = 'abcde'
for k in s:
    if k in dict:     ## 키가 존재 하는 경우
        dict[k] += 1
    else:             ## 키가 존재 하지 않는 경우 
        dict[k] = 1
        
dict
{'a': 2, 'b': 3, 'c': 5, 'd': 1, 'e': 1}

 

 

하지만 이를 대신할 수 있는 방법이 존재한다.  이는 위에서 언급한 setdefault,  defaultdict  함수를 이용하는 것이다.

 

1. 딕셔너리의 setdefalut() 함수이용

s = 'abcdef'
dict = {'a' : 1, 'b' : 1, 'c': 1}

for k in s:
    dict[k] = dict.setdefault(k, 0) + 1
    
dict

---------------------------------------------
{'a': 2, 'b': 2, 'c': 2, 'd': 1, 'e': 1, 'f': 1}

 

dict.setdefalut(k, v) 

k에 해당하는 key가 있을 때, 그 키의 value를 반환하고 k에 해당하는 key가 없을 때, 딕셔너리에 k:v 값을 저장을 하고 v를 반환한다. (dict[k] = v)  

 

 

2. defaultdict() 를 이용하는 방법

from collections import defaultdict

temp = int()
print(temp)

s = 'abcdef'
d = defaultdict(int)

for k in s:
    d[k] += 1

d

----------------------------------------
[실행결과]

0
defaultdict(int, {'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1})

 

defaultdict() 모듈에 관해서 간단히 설명해보면 defalutdict 객체를 생성하기 위해서 함수를 등록해야 한다. 위의 코드에서는 int라는 함수를 등록해주었다. int도 함수다! 즉 디폴트값을 생성하는 함수로 int를 등록한 셈이다. 위의 코드에서 알 수 있듯이 int() 함수를 호출하면 0을 반환한다. default값으로 0을 등록해 주었다.

 

또 다른 예를 살펴보자

 

from collections import defaultdict
a = '112223334445'
dict = defaultdict(list)

for char in a:
    dict[char].append(char)
    
print(dict)

-------------------------------------
## 출력 결과 ##
defaultdict(<class 'list'>, {'1': ['1', '1'], '2': ['2', '2', '2'], '3': ['3', '3', '3'], '4': ['4', '4', '4'], '5': ['5']})

 

defaultdict 객체를 생성할 때 위의 예시처럼 list 함수를 등록해 줄 수 있다.  동작원리를 간단하게 살펴보자. 해당 key가 없다면 리스트를 생성해서 반환할 것이고 해당 리스트에 원소를 추가한다. 해당 key가 있다면 해당 리스트에 원소를 추가한다.

 

 

3. Counter 객체 

 

Counter객체의 경우 아이템에 대한 개수를 계산해 딕셔너리를 반환한다. 사용법은 다음과 같다.

 

from collections import Counter

s = ['a', 'b', 'c', 'a', 'a', 'c', 'b', 'a']
b = Counter(s)
print(b)
print(b.most_common(2))

string = "abcdabcaabbcde"
b = Counter(string)
print(b)
print(b.most_common(2))

[output]------------------------------------------

Counter({'a': 4, 'b': 2, 'c': 2})
[('a', 4), ('b', 2)]
Counter({'a': 4, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
[('a', 4), ('b', 4)]

 

Counter 객체의 경우 이처럼 key에는 아이템의 값이 value에는 아이템의 개수가 들어간 딕셔너리를 반환한다.  추가로 Counter 객체에서 빈도수가 가장 높은 요소를 추출하기 위해서는 most_common() 을 사용하면 된다. most_common() 인자로는 몇 개의 요소를 추출할지를 정하는 수를 인자로 지정한다.

 

 

4. OrderedDict 객체  

 

파이썬의 딕셔너리는 버전 3.7부터 저장 순서를 유지한다.

 

dic = {}

dic['a'] = 1
dic['c'] = 3
dic['b'] = 2

dic
------------------------

{'a': 1, 'c': 3, 'b': 2}

 

a, c, b의 순서로 딕셔너리에 키와 값을 저장하였다. 출력 결과를 보면 a, c, b의 순서로 출력됨을 알 수 있다. 이는 딕셔너리가 내부적으로 저장 순서를 기억하기 때문이다. 그러면 저장 순서를 유지하는 OrderedDict가 필요한 경우는 언제일까? 딕셔너리가 기본적으로 저장 순서를 기억하고 있는데.. OrderedDict는 필요 없는 거 아닌가?

 

 

dic2 = {}

dic2['a'] = 1
dic2['b'] = 2
dic2['c'] = 3

print(dic)
print(dic2)
print(dic == dic2)  ## 서로 저장 순서는 다르지만 True를 반환

--------------------
{'a': 1, 'c': 3, 'b': 2}  ## dic
{'a': 1, 'b': 2, 'c': 3}  ## dic2
True

 

위의 소스코드의 결과에서 알 수 있듯이 딕셔너리의 내용 비교를( == ) 하는 경우에는 저장 순서를 고려하지 않고 딕셔너리 내부의 Key와 Value의 값이 일치하는 경우라면 True를 반환 함을 알 수 있다.  비교를 하고 싶은데 저장 순서까지 고려하고 싶을 경우에는 OrderedDict 객체를 사용하면 된다.  소스코드로 살펴보자.

 

 

from collections import OrderedDict


dict1 = OrderedDict(a=1, b=2, c=3)
dict2 = OrderedDict(b=2, c=3, a=1)

print(dict1)
print(dict2)

print(dict1 == dict2)

-------------------------------------

OrderedDict([('a', 1), ('b', 2), ('c', 3)])
OrderedDict([('b', 2), ('c', 3), ('a', 1)])
False

 

 

소스코드의 결과는 내부적으로 저장 순서가 다르기 때문에 False를 출력 함을 알 수 있다. 저장 순서까지 모두 일치했다면 True를 반환할 것이다.

 

 

 

 

 

***  참고도서   ***

파이썬 알고리즘 인터뷰

www.yes24.com/Product/Goods/91084402?OzSrank=2

윤성우의 열혈 파이썬 중급편

http://www.yes24.com/Product/Goods/81519650?OzSrank=7

 

 

반응형