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

YangJiWon·2020년 6월 15일
0

python

목록 보기
2/12

서론

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

본론

boj11651

문제

2차원 평면 위의 점 N개가 주어진다. 좌표를 y좌표가 증가하는 순으로, y좌표가 같으면 x좌표가 증가하는 순서로 정렬한 다음 출력하는 프로그램을 작성하시오.

  • 이 문제를 풀다가 정렬을 내 마음대로 조작할 수 없나 생각하게 되었고, 파이썬 docs에서 찾아보다가 결국 알아냈다. (고수분들은 다 알고 있었겠지만..)

입력

0 4
1 2
1 -1
2 2
3 3

결과

1 -1
1 2
2 2
3 3
0 4

어떻게 쓰냐 그러면?

  • 일단 내가 저 문제처럼 원하는 대로 비교할 수 있도록 하나의 비교 함수를 넣어야 한다.
def xy_compare(x, y):
    if x[1] > y[1]: # y좌표가 작은 것부터 앞으로
        return 1
    elif x[1] == y[1]: # y좌표가 같을 경우
        if x[0] > y[0]: # x 좌표가 작은 것이 앞으로 나오게
            return 1
        elif x[0] < y[0]: # x 좌표가 큰 것이 뒤로
            return -1
        else: # 같은 경우에는 그대로
            return 0
    else: # y좌표가 큰 것이 뒤로
        return -1

이렇게 만들고 python2에서는

python2

xy_lst = sorted(xy_lst, cmp=xy_compare)

하면 되지만 python3에서는

python3

from functools import cmp_to_key
xy_lst = sorted(xy_lst, key=cmp_to_key(xy_compare))

위의 cmp_to_key 가져오고 cmp -> key로 변경해주어야 작동한다.

참고

cmp_to_key의 정의

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K:
        def __init__(self, obj, *args):
            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
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

끝!

profile
데이터데이터데이터!!

3개의 댓글

comment-user-thumbnail
2020년 9월 10일

list_name.sort(key=lambda x: (x[0], x[1], ...x[n]))
이런식으로 사용하면 더 편할겁니다.
x[n] 은 정렬의 기준값이 되길 원하는 list속 요소의 n번 인덱스를 의미합니다.
만약, 내림차순 정렬을 하고싶다면 -x[n] 이런식으로 적어주면 됩니다.

1개의 답글
comment-user-thumbnail
2021년 6월 14일

감사합니다. 2에서 3 넘어와서 고생했는데

답글 달기