[파이썬] cmp_to_key : 정렬 기준 커스텀하기

kkado·2024년 3월 20일
0

파이썬

목록 보기
4/4

파이썬에서 sort() 함수는 약방에 감초처럼 많이 쓰인다. 기본적으로 오름차순 정렬을 해 준다.
괄호 안에 reverse=True을 추가해 줌으로써 내림차순 정렬을 할 수 있고,
조금 더 심화된 내용으로 lambda 식을 이용해서 여러 조건을 명시할 수도 있다.

가령 어떤 배열들을 정렬하고 싶은데 먼저 1차적으로는 배열의 길이로 정렬하고, 그 다음에는 배열의 마지막 원소 기준의 내림차순으로 정렬하고 싶다고 하자.
그러면arr.sort(key = lambda x:(len(x), -x[-1])) 이런 식으로 작성할 수 있다.

하지만 만약, 정렬 기준이 더 복잡하거나, 람다 표현식으로 표현하기 힘든 기준을 적용하고 싶을 때는 어떻게 할까. 이 글에서는 이를 해결할 수 있는 조건 정렬 기능을 소개한다.

functools.cmp_to_key

functools 라이브러리 안에 있는 cmp_to_key 를 정의함으로써 정렬 루틴을 직접 만들 수 있다.

cmp_to_key(a, b)는 음수를 리턴하면 a가 더 작은 것으로 간주한다.
0을 리턴하면 둘은 같은 것으로 간주한다.
양수를 리턴하면 a가 더 큰 것으로 간주한다.

이 성질을 이용해서 프로그래머스 : 가장 큰 수 문제를 해결할 수 있다.

이 문제는 어떤 두 수를 이어 붙이는데, 더 크게끔 이어 붙여서 가장 큰 수를 찾아내야 하는 문제이다. 예컨대 [4, 10] 이라면 104보다 410이 크므로 답이 410이다. [3, 30, 34]의 경우 가장 큰 수는 34330이다.

두 수를 문자열로 만들어 서로 이어붙여 보고, 이어붙인 두 수를 비교해서 대소비교를 하는 식으로 정렬 루틴을 구성할 수 있다.

def compare(a, b):
	a = str(a)
    b = str(b)
    
    # a가 앞에 와야 하므로 음수 리턴
    if int(a+b) > int(b+a):
    	return -1
    # a가 뒤에 와야 하므로 양수 리턴
    elif int(a+b) < int(b+a):
    	return 1
    else:
    	return 0

혹은 한 줄로 멋지게 바꿀 수도 있다.

def compare(a, b):
	a = str(a)
    b = str(b)
    return int(b+a) - int(a+b)

이제 이 함수를 sort() 안에 넣어주면 된다.

from functools import cmp_to_key

numbers.sort(key = cmp_to_key(compare))

직접 기준을 명시할 수 있는 방법이 있으면 좋겠다 생각했는데 역시나 있었다.
구글링해보니 나 말고도 다른 많은 사람들이 저 프로그래머스 문제를 통해 이 기능을 처음 접한 것 같았다.

종종 쓰일 수 있는 기능 같아 벨로그에 정리해 둔다!

profile
베이비 게임 개발자

0개의 댓글