key
파이썬에서 제공하는 sorted 기능은 key 파라미터로 커스텀한 기준을 부여하여 정렬할 수 있습니다.
파이썬 sort 관련 독스에서도 이를 확인할 수 있습니다. https://docs.python.org/ko/3/howto/sorting.html#key-functions
"key 매개 변수의 값은 단일 인자를 취하고 정렬 목적으로 사용할 키를 반환하는 함수(또는 다른 콜러블)여야 합니다."
다시 말해 key 파라미터에는 정렬하려는 원본 원소가 들어갔을 때 정렬용 기준값을 뱉어주는 함수를 넘겨주면 된다는 것입니다.
예를 들어 아래 튜플을 나이순으로 정렬하고 싶다고 해보겠습니다.
student_tuples = [
('john', 'A', 15),
('jane', 'B', 12),
('dave', 'B', 10),
]
여기서 정렬하고자 하는 원본 원소인 ('john', 'A', 15) 이 들어갔을 때 '나이' 만 반환하는 함수를 만들어서 key 에 넣어주면 됩니다.
커스텀하게 정의한 함수나 lambda 함수를 사용할 수 있습니다.
# 커스텀 함수 정의
def sort_key(item) :
return item[2]
students.sort(key = sort_key)
# 람다 함수 활용
students.sort(key = lambda x : x[2])
(참고 : sort 메서드는 배열에서만 제공되며, sorted 는 모든 이터러블 객체에 대해 적용할 수 있습니다.)
여러 기준에 대해서 정렬하고자 한다면?
sort 의 stable 한 특성을 활용해볼 수 있습니다.
sort 의 stable 특성이란, "key 값이 동일한 경우 원래의 순서를 유지시킨다" 는 걸 의미합니다.
예를 들어 위의 student_tuples 에서 "등급 순으로 정렬하되, 등급이 같으면 나이 순으로 정렬하고 싶다." 의 경우,
나이순 정렬 후 등급순 정렬 을 시행하면 같은 결과를 얻을 수 있게 됩니다. 적용하는 순서가 바꼈다구요? 맞습니다. 가장 우선순위가 낮은 카테고리부터 정렬시켜주면 됩니다.
나이순으로 정렬하면 다음과 같이 정렬되고,
student_tuples = [
('dave', 'B', 10),
('jane', 'B', 12),
('john', 'A', 15),
]
여기서 등급순으로 한번 더 정렬하게 되면 같은 등급의 원소들끼리는 현재의 상대적 순위를 그대로 유지하면서 우리가 원하던 방식으로 sorted 되게 됩니다.
student_tuples = [
('john', 'A', 15),
('dave', 'B', 10),
('jane', 'B', 12),
]
sort 가 stable 한 특성을 가지고 있기 때문에 가능한 방식입니다. 추가로, 역순 정렬을 원하면 reverse = True 로 파라미터를 주거나, key 값이 수인 경우 -1 을 곱해서 해결할 수도 있습니다.
이걸 원리로 훨씬 복잡한 기준의 정렬도 쉽게 구현할 수 있습니다.
key 에는 대소비교가 가능한 return 값을 가지는 함수는 다 가능하고, 튜플이나 배열도 가장 직관적으로 떠오르는 그 방식 (인덱스 빠른 순서로 크기 비교) 으로 대소 비교가 제공되므로 튜플이나 배열 return 도 가능합니다.
set 도 대소 비교가 (포함관계로 연산됨) 가능하기 때문에 set 를 넣어서 커스텀 해볼 수 도 있겠죠. 포함관계가 성립하지 않는 경우에는 기존의 상대 순서가 유지됩니다.
students.sort(key = lambda x : (x[1], x[2]))
'Languages > Python' 카테고리의 다른 글
[fstring] fstring으로 숫자 포맷팅하기 (0) | 2023.06.28 |
---|---|
[heapq] 최소힙, 최대힙 (0) | 2023.06.27 |
join이 for 보다 빠르다 (제공되는 메서드를 최대한 사용하자) (0) | 2023.06.27 |
[setrecursionlimit] 재귀 깊이 증가시키기 (0) | 2023.06.13 |
[round] 파이썬 round 의 특이한 .5 처리법 (0) | 2023.06.06 |