cmp_to_key

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import functools

def xy_compare(n1, n2):
    if n1[1] > n2[1]:
        return 1
    elif n1[1] == n2[1]:
        if n1[0] > n2[0]:
            return 1
        elif n1[0] == n2[0]:
            return 0
        else:
            return -1
    else:
        return -1

src = [(0, 4), (1, 2), (1, -1), (2, 2), (3, 3)]
result = sorted(src, key=functools.cmp_to_key(xy_compare))
print(result)
[(1, -1), (1, 2), (2, 2), (3, 3), (0, 4)]

Remarks

이 글은 https://wikidocs.net/109303의 참조하여 작성되었습니다.

sorted()의 parameter key의 값으로 일반적으로 단항 함수(unary function)을 사용하지만, functools.cmp_to_key()를 사용하면 2개의 input을 받아 비교할 수 있다. (sorted(), min(), max(), heapq.nlargest(), itertools.groupby() 등에서도 사용가능)

python2에서 python3로 올라오면서 사라진 cmp 인자를 key 인자로 이식할 때 주로 사용되는 프로그램의 전이 도구로 사용된다고 한다.

cmp_to_key()의 input으로 사용되는 함수는 2개의 input(n1, n2)을 받고 (1, 0, -1) 3가지 값 중 하나를 반환해야 한다.

첫 번째 인자가 두 번째 인자보다 큰 경우(__gt__), 양수(1)을 반환
첫 번째 인자가 두 번째 인자보다 작은 경우(__lt__), 음수(-1)을 반환
첫 번째 인자가 두 번째 인자와 같은 경우(__eq__), 0을 반환

다음은 간단한 예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from functools import cmp_to_key

@cmp_to_key
def comp(n1, n2):
    if n1 > n2:
        return 1
    elif n1 < n2:
        return -1
    else:
        return 0

src = [5, 3, 2, 4, 1]
result = sorted(src, key=cmp)
print(result)