https://cuffyluv.tistory.com/123 이전에 작성한 글 참고.
data = [(1, 3, 5, 7, 9), (1, 3, 2, 4, 8), (2, 2, 3, 6, 7), (3, 1, 6, 8, 10)]
result = sorted(data, key=lambda x: (x[1], x[0]))
print(result) # [(3, 1, 6, 8, 10), (2, 2, 3, 6, 7), (1, 3, 5, 7, 9), (1, 3, 2, 4, 8)]
위와 같은 파이썬 코드가 있다.
튜플을 요소로 가지는 리스트에서, 각 요소를 정렬할 건데,
첫 번째 정렬 기준을 튜플의 두 번째 요소,
그리고 위의 첫 번째 정렬기준이 일치할 경우, 튜플의 첫 번째 요소를 정렬 기준으로 하여서 정렬하는 코드이다.
그러면, 튜플의 두 번째 요소와 첫 번째 요소가 일치할 경우, 즉 정렬 우선순위가 동일한 두 요소가 있을 경우,
해당 두 요소는 어떻게 정렬될까?
즉, 위의 예시에 있는 `(1, 3, 5, 7, 9)과 `(1, 3, 2, 4, 8)`는 튜플의 두 번째 요소와 첫 번째 요소가 모두 동일한데,
이 둘끼리는 어떻게 정렬될까?
정답은 기존의 순서인 `(1, 3, 5, 7, 9), (1, 3, 2, 4, 8)`를 유지한다.
파이썬의 `sorted()` 함수는 `안정 정렬(stable sort)`인 `팀소트(Tim sort)`로 구현되어 있기 때문이다.
안정 정렬(Stable sort)
- 같은 우선순위를 가지는 것끼리는 기존의 정렬 순서를 유지하는 정렬.
안정 정렬의 예시
- 병합 정렬(Merge Sort)
- 버블 정렬(Bubble Sort)
- 삽입 정렬(Insertion Sort)
- 계수 정렬(Counting Sort)
- 팀 소트(팀 정렬, Tim sort)
불안정 정렬(Unstable sort)
- 같은 우선순위를 가지는 것끼리 기존의 정렬 순서를 유지하지 않을 수 있는 정렬.
* 오해1: 같은 우선순위를 가지는 것끼리 랜덤으로 섞는 게 아님!!
=> 각 알고리즘에 따라 같은 우선순위인 것들 순서 처리 방식은 차이가 있음.
* 오해2: 무조건 기존의 정렬 순서를 유지하지 않는 게 아님!!
=> 기존의 정렬 순서대로 나올 수도 있음.
- 즉, 정렬 과정에서 자연스럽게 기존 순서가 보장되지 않을 뿐인거지, '랜덤'하게 바뀌는 게 아님.
- 항상 순서가 바뀌는 것은 아니지만, 바뀔 가능성이 있는 것. (물론 일반적으로는 바뀔 가능성이 더 높겠지?)
불안정 정렬의 예시
- 퀵 정렬(Quick Sort)
- 힙 정렬(Heap Sort)
- 선택 정렬(Selection Sort)
파이썬의 경우
- 파이썬의 `sorted()`와 `list.sort()`는 내부적으로 팀 소트를 사용해 구현되어 있어, 안정 정렬이다.
- 또한, `max()` 함수도 (안정 '정렬'이라고 할 순 없지만) 비슷하게 안정적(stable)이어서, 같은 우선순위를 가지는 인자가 있으면 먼저 등장한 인자를 선택한다.
before = "apple"
now = "grape"
result = max(before, now, key=len)
print(result) # apple
- 위는 그 예시. 길이가 같은 두 인자에 대해, 먼저 온 인자 before이 반환된 것을 볼 수 있다.
- 아래 Ref.에 파이썬 공식 문서를 읽어보길 추천.
Ref.
https://docs.python.org/ko/3.13/library/functions.html#sorted
'Programming > Practical Algorithms' 카테고리의 다른 글
[알고리즘] 정적 배열 vs 동적 배열 vs 연결 리스트 차이점 비교 (0) | 2025.02.03 |
---|