정렬과 관련된 문제를 풀다보면 특정 조건으로 정렬을 시켜야 하지만, 그게 잘 안될 때가 있다. 그러다 찾은 방식이 바로 cmp_to_key 를 이용하는 것이다.
아래 설명은 내가 이해한 정도의 지나지 않는다. 틀린 설명이 있을 수도 있으니 감안해서 읽어야 한다.
key는 우리가 보통 .sort()나 sorted()를 사용할 때 그 안에서 정렬조건으로 넣는 그 key를 말한다. 일반적으로는 lambda를 사용해서 비교해보고는 한다.
cmp는 compare 함수를 의미한다! 이와 관련해서 검색하면서 나도 compare 함수를 처음으로 접했다. 예시를 보자
def compare(x, y):
if x+y > y+x:
return -1
elif x+y == y+x:
return 0
else:
return 1
x와 y가 '3'과 같이 str화 되어있는 숫자일 때를 감안한 compare함수이다. return -1의 의미는 앞서서 들어온, 여기서는 x가 되겠는데 이 x가 y보다 앞에 정렬된다는 것이다. return 0 은 순서가 변하지 않는 것이고, return 1은 y가 앞서서 정렬된다는 의미이다.
추후에 알아본 바에 의하면, 그냥 양수를 return 하면 두 input의 자리를 바꾼다는 의미이고, 음수를 return하면 두 input의 위치를 바꾸지 않는다는 의미로 이해해도 될 것 같다. 즉 -1 과 1 같이 return되는 숫자의 크기는 상관이 없다.
즉 정리하자면 아래와 같다.
return 음수 : 먼저 들어온 요소가 앞으로 정렬됨
return 0 : 바뀌지 않음
return 양수 : 나중에 들어온 요소가 앞으로 정렬됨(먼저들어온 요소보다 앞에 배치됨)
from functools import cmp_to_key
l = ['34', '37', '9', '31', '3']
return sorted(l, key=cmp_to_key(compare))
이 결과는 ['9', '37', '34', '3', '31']이 return된다.
살짝만 뜯어보면 '9'와 '37'의 경우 '937' > '379'이기 때문에 9가 먼저 오는 것이고, '31'와 '3'의 경우 '313'<'331'이기에 순서가 바뀌어서 '3'이 '31' 보다 먼저오게 되는 것이다.
이 예시는 프로그래머스의 '가장 큰 수' 문제에 대한 풀이라고 볼 수 있다.
글만 읽어선 뭔가 아리송 하다면 그냥 자신이 생각하는 아무론 조건을 설정하고서 그 조건에 맞도록 compare 함수를 짜보자. 아니면 위 문제를 풀어보는 것도 좋다.
기억해야 할 점은 cmp_to_key를 활용해서 자신만의 조건에 따라 sorting 가능하게 할 수 있다는 점이다. 익혀두면 아주 유용한 스킬이 될 것 같다.