Python] Dictionary

생성방법

1
2
3
4
5
6
d1 = { 'a':1, 'b':2, 'c':3 }
d2 = dict([('a',1), ('b',2), ('c',3)])
d3 = dict(a=1, b=2, c=3)
d4 = dict(zip(['a','b','c'], [1,2,3]))

print(d1 == d2 == d3 == d4) #True

파이썬 3.7부터 dictionary의 순서를 보장하고 있다.

1
2
3
4
d1 = {'a':1, 'b':2, 'c':3}
d2 = {'c':1, 'b':2, 'a':3}

print(d1, d2) #{'a': 1, 'b': 2, 'c': 3} {'c': 1, 'b': 2, 'a': 3}

Default Dictionary

주어진 사람들의 혈액형별 숫자를 구하는 식을 나타내시오.

1
2
3
4
5
6
7
8
9
10
person_list = ['A', 'A', 'AB', 'B', 'O', 'B', 'B', 'A', 'A', 'AB', 'A']
person_dict = {}

for blood in person_list:
if blood in person_dict:
person_dict[blood] += 1
else:
person_dict[blood] = 1

print(person_dict) #{'A': 5, 'AB': 2, 'B': 3, 'O': 1}

setdefault(k, default)

k : 키 값

default : default값

1
2
3
4
5
6
person_dict = {}

for blood in person_list:
person_dict[blood] = person_dict.setdefault(blood, 0) + 1

print(person_dict) #{'A': 5, 'AB': 2, 'B': 3, 'O': 1}

defaultdict()

인자는 3가지를 받을 수 있으나, 아래의 예제만 보자면 함수를 넣으면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#사용법, 쉬운 예제
from collections import defaultdict

d = defaultdict(lambda: 5)
print(d['a']) #5
print(d['c']) #5
from collections import defaultdict

person_dict = defaultdict(int)

for blood in person_list:
person_dict[blood] += 1

print(person_dict) #defaultdict(<class 'int'>, {'A': 5, 'AB': 2, 'B': 3, 'O': 1})

Dictionary sort

버전 3.7이전에는 딕셔너리는 순서를 보장하지 않았다.

이전의 버전에서는 순서를 유지하기 위해서 OrderedDict라는 것을 생성해서 사용했다.

1
2
3
4
5
6
7
8
from collections import OrderedDict

od = OrderedDict() #OrderedDict 객체 생성
od['c'] = 1
od['b'] = 2
od['a'] = 3

print(od) #OrderedDict([('c', 1), ('b', 2), ('a', 3)])

사용법은 딕셔너리와 똑같다. items()를 통해 for문을 이용할 수도 있고 키값으로 값에 접근도 가능하다.

왜 알아야하는가?

버전 3.7에서는 순서를 보장하는데 굳이 왜 순서를 보장하는 이전의 방법을 알아야하는가?

  1. 순서 보장, 값의 비교
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
d1 = { 'a':1, 'b':2, 'c':3 }
d2 = dict([('b',2), ('a',1), ('c',3)])
d3 = dict(b=2, c=3, a=1)
d4 = dict(zip(['a','b','c'], [1,2,3]))

print(d1) #{'a': 1, 'b': 2, 'c': 3}
print(d2) #{'b': 2, 'a': 1, 'c': 3}
print(d3) #{'b': 2, 'c': 3, 'a': 1}
print(d4) #{'a': 1, 'b': 2, 'c': 3}

print(d1 == d2) #True
print(d1 == d2 == d3 == d4) #True
from collections import OrderedDict

od1 = OrderedDict() #OrderedDict 객체 생성
od1['c'] = 1
od1['b'] = 2
od1['a'] = 3

od2 = OrderedDict()
od2['a'] = 3
od2['c'] = 1
od2['b'] = 2

print(od1) #OrderedDict([('c', 1), ('b', 2), ('a', 3)])
print(od2) #OrderedDict([('a', 3), ('c', 1), ('b', 2)])
print(od1 == od2) #False

OrderedDict는 순서도 보장하지만, 값에 대한 순서 비교도 보장하고 있음을 알 수 있다.

  1. 저장 순서 변경 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from collections import OrderedDict

od = OrderedDict() #OrderedDict 객체 생성
od['c'] = 1
od['b'] = 2
od['a'] = 3

print(od) #OrderedDict([('c', 1), ('b', 2), ('a', 3)])

od.move_to_end('b', last=True)
print(od) #OrderedDict([('c', 1), ('a', 3), ('b', 2)])

od.move_to_end('a', last=False)
print(od) #OrderedDict([('a', 3), ('c', 1), ('b', 2)])

move_to_end(key, last=True/False)를 이용하여 저장 순서를 변경할 수도 있다.

last를 True로 하면 제일 뒤로 보내지고, False로 하면 제일 앞으로 보내지게 된다.

zip함수

zip(\*iterable)은 동일한 개수로 이루어진 자료형을 묶어 주는 역할을 하는 함수

1
2
3
4
5
6
7
8
9
10
11
12
a = ['a','b','c']
b = [1,2,3]
c = "ABC"

for i in zip(a,b,c):
print(i)

"""
[출력]
('a', 1, 'A')
('b', 2, 'B')
('c', 3, 'C')