초보 개발자

17강 dict & OrderedDict 본문

Python/윤성우 열혈 파이썬

17강 dict & OrderedDict

taehyeki 2021. 12. 24. 13:33

[dict은 저장 순서를 유지하기 시작했다.]

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

 

d = {}
d['a'] = 1 # 제일 먼저 저장
d['b'] = 2 # 두 번째로 저장
d['c'] = 3 # 마지막에 저장
d
{'a':1,'b':2,'c':3}
for kv in d.items():
	print(kv)
('a', 1)
('b', 2)
('c', 3)

지금은 순서대로 출력을 잘 해주지만

예전에는 이렇게 순서를 보장해주지 않았다.

 

a=1 b=2 c=3
b=2 a=1 c=3

위의 두 행의 값들은 다 같다

만약 순서 또한 고려하는 상황이라면 이 두 행은 엄연히 다르다고 할 수 있다. 

 

dict같은 경우에는 저장 순서를 유지하고 있긴하지만 저장 순서를 infomation이라고 인정을 하지 않는다.

즉 dict의 입장에서 위의 코드는 같다고 인식한다.

 

그러나, OrderedDict같은 경우에는 저장 순서도 유지하고 저장 순서를 infomation이라고 인정을 한다.

따라서 OrderedDict같은 경우에는 위의 코드는 다르다고 인식한다. (순서가 다르니까)

 

둘 다 dict이라는 기본 성격은 같지만 엄연히 다른 애들이다.

 

내가 쓸 데이터가 저장 순서를 infomation으로 보는 애들인지 아닌지에 따라서 사용여부가 갈린다.

 

from collections import OrderedDict # collections 모듈의 OrderedDict
od = OrderedDict() # OrderedDict 객체 생성
od['a'] = 1 # 딕셔너리 사용 방법과 동일
od['b'] = 2
oc['c'] = 3
od
OrderedDict([('a',1),('b',2),('c',3)])
for kv in od.items(): # 딕셔너리와 마찬가지로 items 메소드 호출 가능
	print(kv)
    
('a', 1)
('b', 2)
('c', 3)

OrderedDict는 저장 순서도 중요한 정보라고 생각한다. 저장 순서가 유지되는 것을 볼 수 있다.

하지만 이제는 일반 딕셔너리도 저장 순서를 유지하기 때문에 OrderedDict를 단지 순서를 유지하기 위해서만으론 사용할 필요가 사라졌다,

 

[그래도 OrderedDict을 써야 할 이유가 있다면?]

다음 두 예제의 실행결과를 비교해보자 먼저 dict의 예이다.

d1 = dict(a = 1, b = 2, c = 3)
d2 = dict(c = 3, a = 1, b = 2)
d1
{'a':1,'b':2,'c':3}
d2
{'c':3, 'a':1, 'b':2}
d1 == d2 # d1, d2는 저장순서는 다르고 내용물은 같다.
True

dict : 내가 저장순서는 유지하고 있을 지 언정, 난 이걸 infomation으로 인정하지 않아 ! 저장순서는 나의 관심사가 아니야~ 

즉 dict는 저장된 내용물만 동일하면 == 연산 결과가 True이다. 저장순서는 dict 객체를 비교함에 있어서 비교대상이 아니다.

 

 

from collections import OrderedDict
od1 = OrderedDict(a = 1, b = 2, c = 3)
od2 = OrderedDict(c = 3, a = 1, b = 2)
od1
OrderedDict([('a',1),('b',2),('c',3)])
od2
OrderedDict([('c',3),('a',1),('b',2)])
od1 == od2 
False

OrderedDict 객체 비교에 있어서는 저장 순서도 중요하다!!

아무리 내용물이 동일하여도 저장 순서가 일치하지 않으면 == 연산의 결과는 False이다. 따라서 딕셔너리의 저장 순서가 객체 구분에 의미를 갖는 상황이면 OrderedDict를 사용해야 한다.

 

 

move_to_end 메소드

from collections import OrderedDict
od = OrderedDict(a=1, b=2, c=3)
for kv in od.items():
	print(kv, end = ' ')

('a', 1) ('b', 2) ('c', 3)

od.move_to_end('b') #키가 'b'인 키와 값을 맨 뒤로 이동
for kv in od.items():
	print(kv, end = ' ')

('a', 1) ('c', 3) ('b', 2)

od.move_to_end('b', last = False) # 매개변수 last에 False 전달하면 맨 앞으로 이동
for kv in od.items():
	print(kv, end = ' ')

('b', 2) ('a', 1) ('c', 3)

맨 앞으로 이동시키려면 move_to_start와 같이 써줘야 한다고 생각하지만 

move_to_end에 last = False옵션을 주면 맨 앞으로 이동을 한다.

 

따라서 저장 순서 자체가 하나의 정보로써 의미를 갖는다면, 그리고 저장순서를 바꿔야 할 가능성도 존재한다면

OrderedDict를 선택해야 한다.