최근의 python은 dictionary가 순서가 보장됩니다. 넣은 순서가 유지되는 특성이 있습니다. 여기서 궁금한 점. 그러면 어떻게 가장 먼저 넣은 키와 나중에 넣은 키를 알 수 있을까요? 파이썬의 dictionary와 orderedDict는 popitem 함수가 있습니다. 이 함수는 기본적으로 가장 마지막에 추가한 원소를 제거하면서 가져오는 역할을 합니다. 한 번 사용해 보겠습니다.

 


 먼저, 1부터 4까지 순서대로 OrderedDict에 추가합니다. 다음에, 7번째 줄에 루프를 돌면서, popitem으로 가장 마지막에 추가된 원소를 빼오게 됩니다. 1부터 4까지 있었을 때에는 가장 마지막에 있었던 것이 4입니다. 따라서, 4가 빠질 겁니다. 다음에 1부터 3까지 있을 때에는 가장 마지막에 있던 것이 3입니다. 그 다음에는 3이 빠질 겁니다.

 

 이런 식으로 계속 빼다 보면 다 빠질 겁니다. 즉, 4, 3, 2, 1 순으로 빠지게 됩니다.

 

 실행 결과를 보면, (4, 4), (3, 3), (2, 2), (1, 1) 순서대로 나왔음을 알 수 있습니다.

 

 이제 last=False 옵션을 줘 보겠습니다. 이 경우, 처음에 추가한 것이 나오게 됩니다. 1 ~ 4중에 1이 먼저 추가되었으니 1이 먼저 나오게 됩니다. 다음에 2가 나오고, 3이 나오고, 4가 나오는 식입니다.

 

 

 여기까지 이해하는 데 별 어려움이 없습니다. 결국 딕셔너리에서 가장 마지막에 추가된 원소를 제거하기 위해서 popitem 메서드를 호출합니다. 첫 원소를 제거하기 위해서는 last=False를 줘야 하는데요. 문제는 OrderedDict에 이 옵션이 있다는 점입니다. 딕셔너리에는 popitem에 이러한 옵션을 줄 수 없습니다.

 


 실제로, 그냥 딕셔너리를 쓰게 되면, 가장 먼저 추가된 원소를 가져오기 위해 이런 코드를 입력해야 합니다. next(iter(md)). 딕셔너리의 이터레이션을 얻어온 다음에 next를 호출하는 식입니다.

 

 1, 2, 3, 4 순서대로 얻어왔음을 알 수 있습니다. 이 로직은 효율적으로 동작할까요? timeit을 써서 간단하게 측정해 보겠습니다.

 

 

 func 함수는 간단합니다. 딕셔너리를 생성하고 n개의 아이템을 넣습니다. 그리고, n회에 걸쳐서 가장 먼저 추가된 원소를 빼오게 됩니다. n이 10만일 때와 20만일 때 실행 시간을 측정해 보겠습니다.

 

 3.02초와 12.51초. 데이터 크기가 2배나 증가했는데, 실행 시간은 무려 4배나 증가했습니다. 비효율적이라는 것입니다. 그러면 어떻게 해야 할까요? 딕셔너리 대신에 OrderedDict을 쓰고, popitem에 last=False 옵션을 주면 됩니다. 이렇게 한 번 해 보겠습니다.

 

 

 다른 건 변화가 없습니다. 단지, 딕셔너리 대신에 OrderedDict을 썼습니다.

 

 실행 시간을 보니 0.02초, 0.06초가 나왔습니다. 확실히 효율적으로 동작함을 알 수 있습니다.