본문 바로가기
Python/알고리즘팁

파이썬 커스텀 정렬 이용하기

by 붕어사랑 티스토리 2021. 3. 10.
반응형

파이썬 3.x 이상 버전

from functools import cmp_to_key

def comp(x, y):
    if x[0]<y[0]:
        return True
    elif x[0] == y[0]:
        return 0
    else:
        return -1

l = []
l.append((1,4))
l.append((3,1))
l.append((2,2))
l.append((4,5))

sorted_list = sorted(l, key=cmp_to_key(comp))

print(sorted_list)

functools 에서 cmp_to_key를 임포트하여 sorted 함수의 key 값에다 커스텀한 comparator를 cmp_to_key에 담아넘겨준다.

 

결과

[(4, 5), (3, 1), (2, 2), (1, 4)]

 

 

여기서 주목할점은 

바로 이부분

 

c 처럼 True False로 하는게 아니라 양수, 음수 이런식으로 해주어야 한다.

c 에서 strcmp에서 리턴값이 1, 0, -1 인것을 생각하면 쉽게 이해가 된다.

 

여기서 0은 두 값이 같을때를 나타낸다.

 

True False로 해줬더니 계속 커스텀한 정렬이 안돼서 시간 오지게 날렸다 ㅡㅡ

 

몇번 실행해본 결과 값이 같은경우 0을 리턴해주는것은 필요 없어보이긴 하다.

 

cmp_to_key 소스를 분석해보니 크고 작음을 양수 음수로 구분하고있다.

 

True가 1이고 False가 0이다. 아래 소스코드를 기준으로 얘기하면 False는 equal인 셈이 되는것이다.

 

고로 1, -1을 이용하자

def cmp_to_key(mycmp):
    """Convert a cmp= function into a key= function"""
    class K(object):
        __slots__ = ['obj']
        def __init__(self, obj):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        __hash__ = None
    return K

 

리스트 내부 sort 안에 custom comparator를 넣어주는 케이스도 위와 동일하다.

l.sort(key=cmp_to_key(comp))

 

 

 

 

파이썬 2.x 버전

 

def custom_cmp(x, y):
    if x[0] > y[0]:
        return True
    else:
        return -1


l = []
l.append([3,1])
l.append([4,5])
l.append([2,2])
l.append([1,4])
sorted_list = sorted(l, cmp = custom_cmp)
print(sorted_list)

2,x 버전에서는 key 대신에 cmp변수에다가 custom comparator를 넣어준다.

 

얘도 마찬가지로 return값을 True False가 아닌 양수, 음수로 해주어야 된다.

 

편의상 True와 -1로 표시했는데 1, -1 로 사용하도록 하자.

 

 

 

 

 

근데 사실 이거보다 좋은건 두개의 데이터를 튜플로 묶고, 부호만 바꿔서 정렬해주는게 속도도 빠르고 코드도 짧다

 

 

반응형

댓글