본문 바로가기
🍃 Language/Python

[Python] 커스텀한 기준으로 sort()하기 cmp_to_key()

by 카프리썬_ 2021. 7. 12.
728x90
728x90

이문제를 풀다가 알게된 새로운함수 python내용

 

list.sort()  key 파라미터로 lambda 함수를 넘겨 주어, element의 정렬 조건을 설정했다. 

그러니까 lambda에 정렬기준을 '직접' 입력한 것이다. 

예를들어 튜플의 1번째 글자를 기준으로 내림차순 정렬한다고 하면 이렇게 x[1]을 정렬기준으로 지정해줬다. 

arr = [(1, 2), (2, 3), (1, 3), (2, 4), (3, 4)]
arr.sort(key=lambda x: x[1], reverse=True)  # 튜플 1번째 값으로 정렬
print(arr)

앞서 한번 정리한적있다. lambda로 sort하는 방법.

https://pearlluck.tistory.com/462

 

[Python] 람다식, lambda로 sorted key 정하기

Lambda 함수 이름없는 함수, 람다표현식을 익명함수(anonymous function) 함수를 따로 선언하지 않고, lamba식으로 대체함 예를 들어 매개변수 x에 10을더한 값을 반환하는 함수를 만든다고 하면 사용법

pearlluck.tistory.com

 

 

하지만,  이렇게 lambda로 정렬기준을 콕집어낼 수 없을 경우는?

그러니까 어떤경우에는 앞으로 가서 정렬하고, 어떤경우에는 뒤로 보내서 정렬하고, 어떤경우에는 제자리게 있도록.

이렇게 커스텀한 정렬기준을 가지고 정렬을 할 수 있는 방법이 있다. 

 

python 공식문서에도 나와있는 cmp매개변수를 사용하는 방법이다 

list.sort()를 수행할때, key 파라미터로 functools.cmp_to_key(함수명)을 넘겨주는 것이다.

python2의 경우 cmp=함수명 

python3의 경우 cmp파라미터 대신 cmp_to_key파라미터를 사용한다. 

 

보통 아래와 같은 조건일때 cmp파라미터를 사용한 커스텀정렬방식을 자주사용한다. 

lambda로 정렬하는 기준과 다르게 정렬기준이 2개이상이다.

 

좌표를 y좌표가 증가하는 순으로, y좌표가 같으면 x좌표가 증가하는 순서로 정렬 >>문제출처 : 백준 

위와 같이 lambda로 정렬을 한 내용을 cmp매개변수를 사용해서 아래처럼 수정할 수 있다.

커스텀한 정렬기준을 만드는 함수 xy_compare를 직접 만들어주는 것이다. 

이때, 리턴값은 항상 1,-1,0 이여야한다.

1은 정렬기준대로 앞으로 가기 위해 True를 의미하고,

-1은 정렬기준과 반대로 가서 뒤로가기 위해 False를 의미하고, 

0은 아예 정렬기준에 해당하지 않아 그대로 있을때를 의미한다. 

 

from functools import cmp_to_key  # cmp_to_key가 필요한 경우 import

def xy_compare(a, b):
    if a[1] > b[1]: # y좌표가 작은 것부터 앞으로 가게 정렬
        return 1
    elif a[1] == b[1]: # y좌표가 같을 경우
        if a[0] > b[0]: # x 좌표가 작은 것부터 앞으로 가게 정렬
            return 1
        elif a[0] < b[0]: # x 좌표가 큰 것은 뒤로 가게
            return -1
        else: # 같은 경우에는 그대로
            return 0
    else: # y좌표가 큰 것이 뒤로 가게
        return -1
        
xy_lst = sorted(xy_lst, key=cmp_to_key(xy_compare))

 

앗, 이걸 알기전에 나는 그저 좌표값이라 2개니까 람다에 기준 2개(x,y) 직접 지정했었다;;;물론이게 편하니까

num.sort(key=lambda x:(x[1],x[0]))

 

 

추가로 한가지 더 살펴보면 해커랭크의 문제는 

이름과 성적을 정렬하는 것이였따.

이름이 증가하는 순으로 정렬하고, 점수가 같으면 이름이 증가하는 순서로 정렬 >>문제출처 : 해커랭크

    def comparator(a, b):
        if a.score == b.score: #점수가 같으면 
            if a.name>b.name: #name이 큰 순서대로 
                return 1
            else: #name이 작은 순서는 반대
                return -1
        else: #점수가 다르면, 점수가 큰 순서대로 
            return b.score-a.score
data = sorted(data, key=cmp_to_key(Player.comparator))
for i in data:
    print(i.name, i.score)

 

 

출처 

https://justkode.kr/python/pygorithm-3

 

파이썬으로 알고리즘을 풀어보자! - 3. 팁

Python, Algorithm, Tips Python은 알고리즘 문제를 해결 하는데에 강력한 언어 입니다. 하지만, Python으로 문제를 해결 하는 데에 익숙치 않다면, 많은 시행착오를 겪게 됩니다. 우리가 대부분 원래 사용

justkode.kr

https://velog.io/@sparkbosing/python-%EB%82%B4-%EB%A7%88%EC%9D%8C%EB%8C%80%EB%A1%9C-%EC%A0%95%EB%A0%ACsort

 

python 내 마음대로 정렬(sort)!

아 파이썬도 자바처럼 정렬을 조작할 수는 없나..라는 생각은 가지고 있었지만정말 있는지는 몰랐다.당연히 있었겠지만 나는 이제야 알아버렸다.그 내용을 정리해보고자 한다!2차원 평면 위의

velog.io

 

728x90
반응형