안녕하세요. 이번 시간에는 파이썬 operator의 itemgetter 함수에 대해 알아봅시다.

 


 먼저, itemgetter 함수는, callable object를 리턴한다고 되어 있어요. 그래서, f = itemgetter(2)를 하면, f(r)을 불렀을 때 r[2]가 리턴된다고 되어 있습니다. 이게 무슨 소리인지 문서에 나와 있는 코드를 보겠습니다.

 

 

 대충 요런 함수인데요. 일단은 뭔가 리턴하는데 g를 리턴해 버립니다. 그리고 이 g는 obj를 받습니다. 이로 미루어 보았을 때, 함수 itemgetter는 호출 함수인 caller를 리턴하고, 이 caller가 실제로 iterable한 놈을 넘겨받아서 x번째 원소를 리턴하는 일을 수행한다고 봐도 되겠군요. 그러면 이걸 어떻게 바깥에서 쓸까요?

 

 

 먼저, 2번째 원소를 리턴한다는 함수를 itemgetter를 통해서 리턴받습니다. 이것이 u입니다. 그러면, lt를 넘겼을 때, lt의 2번째 원소를 리턴할 겁니다.

 

 7이 나오네요. 그러면 이것을 어디에 써 먹을 수 있는가? 정렬에 쓰일 수 있다고 문서에도 언급되어 있습니다.

 


 key는 key인데, 어떻게 뽑을 것인가? itemgetter(1)로 1번째 원소를 뽑아낼 겁니다. 리스트에 있는 4개의 데이터에 대해서, 정렬의 기준이 되는 키 값을 뽑아내면 각각 2, 3, 7, 4가 됩니다.

 

 

 이를 기준으로 정렬하면, (1, 2), (1, 3), (-1, 4), (-1, 7)이 됩니다. 이제 두 개의 필드를 기준으로 정렬해 봅시다. 1번째 기준은 1번째 필드 오름차순으로, 2번째 기준은 0번째 필드 오름차순으로 말입니다.

 

 

 그럴려면 단순하게, itemgetter(1, 0)을 입력해 주시면 됩니다. 그러면 각각 순회를 하긴 할 텐데, 1번째 원소, 0번째 원소를 기준으로 키를 뽑아올 겁니다. 1번째 데이터는 (2, 1), 2번째 데이터는 (2, -1), ... 이런 식으로요. 즉, 1번째 원소를 1순위로, 0번째 원소를 2번째 기준으로 뽑아올 겁니다.

 

 따라서 정렬이 위와 같이 되는 것은 그리 이상한 일이 아닙니다. 만약에, 1번 정렬 기준이 1번째 원소는 오름차순으로 정렬, 2번째 정렬 기준을, 0번째 원소 내림차순이라면 어떻게 해야 할까요? 이건 다소 복잡합니다. complex 합니다. 이럴 때 쓸 수 있는 마법의 패턴이 있습니다. 정렬 기준 역정렬. 즉, 2번째 정렬 기준으로 먼저 정렬해 버린 뒤, 1번째 정렬 기준으로 sorting 해 버리는 것입니다.

 

 

 먼저, 3번째 줄에서, 0번째 원소를 기준으로 정렬을 하는데, 내림차순으로 정렬합니다. 그러면 정렬 결과는 어떻게 나올까요? (1, 2), (1, 3), (-1, 2), (-1, 7), (-1, 4), (-1, 5)가 나올 겁니다. 1차 정렬이 종료되었습니다. 다음에 이 결과를 가지고 또 정렬해 버립니다. 4번째 줄에서 1번째 원소 오름차순으로 정렬을 하는데요.

 

 

 그러면 요래 나와요. (1, 2)와 (-1, 2)의 자리가 바뀌지 않았음을 보세요. 이는, python의 정렬 알고리즘이 stable 하기 때문에 가능합니다.