파이썬에는 dict와 OrderedDict가 있습니다. 이 둘에 대해 간단하게 알아봅시다.

 


 아래 코드를 wandbox에서 python 3.5.0에서 실행시켜 보았습니다.

 

 

 2번째 줄이 조금 길어보이는데요. 그리 어렵지 않습니다. ord('A')와 ord('Z')는 'A'와 'Z'를 코드로 변환시켜 줍니다. 그러면 i는 'A'의 코드값부터 'Z'의 코드값까지 돌 겁니다. 그런데, 앞에 chr(i)가 있으니, 결론적으로 li는 'A'부터 'Z'까지 들어가 버리게 됩니다. 3번째 줄에서는 li 안에 있는 것들을 돌면서, 'A', 'B', ... , 'Z' 순서대로 넣고 있습니다.

 

 다음에, 5번째 줄에서는 dic를 순회하면서 요소들을 모두 출력합니다.

 

 

 결과는 위와 같습니다. 중요한 것은 넣은 순서가 자료구조 내에서 유지되지 않았다는 것입니다.

 

 

 해시 테이블의 구조를 보면, 알 수 있습니다. 2는 0번 버킷에 있고, 1, 3이 1번 버킷에 할당된다면, 1, 2, 3 순서대로 넣었다고 할 지라도, 해시에 넣으면 2, 1, 3 순으로 조회가 될 겁니다. head를 모르고, tail도 모르고 노드 간의 연결 관계가 없다면 넣어진 순서를 알 방법이 없습니다. 같은 버킷 내에서만 넣어진 순서를 알 뿐. 위상 정렬이 된 결과가 주어졌을 때, 나올 수 있는 순서가 여러가지일 수도 있다는 점을 생각해 보시면 됩니다.

 

 

 순서가 보장된다면, head와 tail 값을 가지고 있어야 할 겁니다. head는 처음 위치를 찾기 위해서, head는 마지막 위치를 찾기 위해서입니다. 여기서 head는 1이고, tail은 3인데요. 다음에 5가 버킷 2번에 추가되었다고 해 봅시다.

 

 

 그러면, 기존 tail이 가리키는 3과, 새로 추가된 5가 연결이 되고, 새로운 tail은 5를 가리키게 됩니다. 다시 head가 가리키는 1부터 탐색하면, 2, 1, 3, 5 순으로 탐색할 수 있습니다. java의 linkedhashmap이 이런 식으로 구현이 되어 있다는 것은 해당 글에서 언급한 적이 있습니다.

 


 그래서, 예전에는 OrderedDict를 이용하곤 했습니다. 사용 방법은 간단합니다.

 

 

 단지 저는 dictionary를 OrderDict에 넘겼을 뿐입니다. 다른 것은 위에서 언급한 프로그램과 같습니다.

 

 

 아까와는 다르게 순서가 유지되었음을 알 수 있습니다.

 


 그런데, 이 문서이 질답글을 보면, 3.7 버전부터 넣는 순서가 유지됨이 보장된다는 것을 알 수 있습니다. 정말 그런지 알아봅시다. 먼저, python의 version을 알아내는 명령은 python --version입니다.

 

 

 가상 환경에서 이 명령어를 쳐 보니, 3.9.1이 나오는군요. 3.7 이후입니다.

 

 

 코드는 동일합니다. 단지 파이썬 버전만 바뀌었을 뿐입니다.

 

 

 프로그램의 실행 결과를 보면, A, B, C, D, E, ... 이 순서대로 나옵니다. 즉, 넣은 순서가 유지됨을 알 수 있습니다.