파이썬 스터디

[Python] 파이썬 sorted(), 커스텀 정렬,

MINU.SHINNNN 2024. 7. 18. 23:15

정렬을 수행할 때 단순히 한 항목에 대해서만 정렬하는 것이 아니라, 여러 항목에 정렬을 적용해야 하는 경우가 많다.

이 때, 커스텀 정렬이 필요하다.

 

파이썬 정렬에 익숙하지 않아서 그런지 C++보다 여러 항목에 대한 정렬이 조금 어려운 느낌이다. 

C++은 True, False로만 리턴하면 되는데 파이썬은 1, 0, -1을 리턴해야 한다...

 

직관적으로 이해하기 어려워서 그냥 1이면 C++의 True, -1이나 0이면 C++의 False로 이해해버렸다.

 

아래는 functools 의 cmp_to_key 를 사용해 custom sort 함수인 compare_students를 key로 넘겨주는 예제이다.

 

name에 대해서는 내림차순, 나이와 점수에 대해서는 오름차순 정렬하고자 하였다.

 

C++ 스타일 같지만 원하는대로 잘 동작한다.

from functools import cmp_to_key

class Student:
    def __init__(self, name, age, grade):
        self.name = name
        self.age = age
        self.grade = grade
    
    def __repr__(self):
        return f"Student(name={self.name}, age={self.age}, grade={self.grade})"

students = [
    Student('jane', 22, 'C'),
    Student('sally', 17, 'C'),
    Student('sally', 17, 'B'),
]

def compare_students(student1, student2):
    # 이름을 내림차순으로 정렬, 나이, 점수는 오름차순 정렬
    
    if student1.name > student2.name:
        return -1
    elif student1.name == student2.name:
        if student1.age < student2.age:
            return -1
        elif student1.age == student2.age:
            if student1.grade <= student2.grade:
                return -1
            else:
                return 1
        else:
            return 1
    else:
        return 1

# result = sorted(students, key=lambda student: (-ord(student.name[0]), student.age, student.grade))
# result = sorted(students, key=lambda student: (student.name[::-1], student.age, student.grade))
result = sorted(students, key=cmp_to_key(compare_students))

print(result)