파이썬의 sorted () 함수는 안정적입니까?


96

문서는 것을 보증하지 않습니다. 문서화 된 다른 장소가 있습니까?

목록의 정렬 방법이 안정적이라는 것이 보장되고 (참고 9 번째 포인트 : "Python 2.3부터는 sort () 방법이 안정적으로 보장됩니다.") 정렬이 기능적으로 유사하기 때문에 안정적 일 수 있다고 생각합니다. 그러나 나는 그렇게 말하는 확실한 출처를 찾을 수 없습니다.

목적 : 두 레코드에서 기본 키가 동일한 경우 기본 키와 보조 키를 기준으로 정렬해야합니다. sorted ()가 안정적이라면 보조 키를 정렬 한 다음 기본 키를 정렬하여 필요한 결과를 얻을 수 있습니다.

추신 : 혼동을 피하기 위해, "동일하게 비교되는 요소의 상대적 순서를 변경하지 않는 것이 보장된다면 일종의 안정적입니다"라는 의미에서 stable을 사용하고 있습니다.

답변:


127

예, 매뉴얼의 의도는 실제로 sorted그것이 안정적이고 실제로 sort방법 과 정확히 동일한 알고리즘을 사용함 을 보장하는 것 입니다 . 문서가이 신원에 대해 100 % 명확하지 않다는 것을 알고 있습니다. doc 패치는 항상 기꺼이 받아 들여집니다!


2
튜플이나 목록을 정렬하는 경우 "기본"정렬 키가 같을 때마다 "보조"키를 기준으로 정렬됩니다. 예를 들면, sorted([(1, 2), (1, 1)])반환 [(1, 1), (1, 2)]대신 동일한 시퀀스 / 순서에서 일본어 입력 돌리는. 안정성 보장은 원래 [(1, 2), (1, 1)]입력을 반환해야 함을 의미하지 않습니까? 이 경우, 당신은 명시 적으로 말해야합니다sorted([(1, 2), (1, 1)], key=lambda t: t[0])
code_dredd

10
이 경우 예상되는 것이 아닙니까? 파이썬은 기본적으로 첫 번째 "기본"요소가 아닌 모든 요소를 ​​통해 튜플을 비교합니다. 첫 번째 요소 만 정렬하려는 경우 key매개 변수를 명시 적으로 전달할 수 있습니다 .
Matias Grioni 2017

2
@code_dredd 이것은 예상되는 동작입니다. 안정적인 정렬의 요점은 "정렬 키"를 사용하여 정렬하는 것이지만 동일한 정렬 키를 가진 두 개의 다른 요소는 동일한 순서를 갖습니다. 튜플의 기본 정렬 키는 튜플의 모든 요소입니다.
guyarad

27

그들은 안정적 입니다.

그건 그렇고, 단일 패스 정렬에서 다중 패스 정렬을 결합하여 정렬 및 정렬이 안정적인지 여부를 알지 못하는 경우가 있습니다.

정렬 할 경우 예를 들어, 자신을 기준으로 개체 last_name, first_name속성, 당신은 한 번에 그것을 할 수 있습니다 :

sorted_list= sorted(
    your_sequence_of_items,
    key= lambda item: (item.last_name, item.first_name))

튜플 비교를 활용합니다.

이 대답은있는 그대로 원래 질문을 다룹니다. 정렬과 관련된 추가 질문은 Python Sorting How-To를 참조하십시오 .


4
정렬을 반대로하려면 원하지 않는 효과가있을 수 있습니다. 예를 들어 제품을 정렬 할 때 먼저 등급 (오름차순)을 기준으로 정렬 한 다음 가격 (오름차순)을 기준으로 정렬 할 수 있습니다. 이를 반대로하면 내림차순으로 등급을 정렬하고 오름차순으로 가격을 정렬하려고합니다. 이 솔루션에서는 작동하지 않습니다.
Remco Wendt 2012 년

2
@RemcoWendt : 설명하는 내용에 대한 요구 사항이 없었습니다. 어쨌든 인수 대신 key= lambda item: (-item.rating, item.price)a cmp를 고려 하거나 제공하십시오 key. 그래도 귀하의 의견의 목적은 확실하지 않습니다.
tzot 2012 년

1
실제로 이것은 요구 사항은 아니지만 다른 사람들이 이것을 읽고 솔루션을 선택하거나 Python의 안정적인 정렬 기능을 사용할 때이 미묘한 차이를 지적하고 싶었습니다.
Remco Wendt

내가 참조. 즉, 성능에 신경 쓰지 않는 한 쌍으로 정렬하는 것이 더 명확하므로 바람직합니다. 두 개의 안정된 정렬이 한 쌍으로 정렬하는 것보다 다소 빠르다고 상상할 수 있지만 차이는 무시할 수 있습니다.
Sergey Orshanskiy

8
@tzot 내가 언급하고 싶은 것은 항상 안정적인 정렬에 대한 요구 사항이 있습니다. 예를 들어 튜플 (비율, 댓글) 목록이 있고 댓글은 작성된 순서대로 저장되며 비율별로 정렬하고 시간 순서를 유지하고 싶지만 저장하지 않았습니다. 목록의 타임 스탬프. 간단히 말하면 목록을 요금별로 정렬하고 댓글을 동일한 순서로 유지하고 싶습니다.
wsysuper 2015

3

그 동안 변경된 문서 ( 관련 commit )와 현재 문서는이를 sorted명시 적으로 보장합니다.

내장 sorted()기능은 안정적입니다. 동일하게 비교되는 요소의 상대적 순서를 변경하지 않도록 보장하는 경우 정렬은 안정적입니다. 이는 여러 단계로 정렬하는 데 유용합니다 (예 : 부서별 정렬, 급여 등급별 정렬).

어떤 있도록 문서의이 부분은 파이썬 2.7 및 파이썬 3.4 (+)에 추가 된 준수 해당 언어 버전의 구현해야 안정을 sorted.

CPython의 경우 Python 2.3list.sort 부터 안정적이었습니다.

  • Tim Peters는 그의 list.sort()구현을 다시 작성했습니다. 이것은 "안정된 정렬"(동일한 입력이 출력에서 ​​동일한 순서로 나타남)이며 이전보다 빠릅니다.

나는 100 % 확신하지 못합니다 sorted. 요즘은 간단하게 사용 list.sort하지만 그 기록을 확인하지는 않았습니다. 그러나 "항상"을 사용했을 가능성이 높습니다 list.sort.


0

파이썬 2.4 "의 새로운"문서가 효과적으로 "공식적인"문서에 당신은 아니지만 필요가 정렬 된 점을 () 첫 번째는 다음 목록을 작성 보장을 제공하고, 그것을 일종의 ()를 호출합니다. 정말로 걱정된다면 소스를 확인할 수도 있습니다.


1
어디라고 적혀 있나요? sorted () "내부 list.sort ()와 같이 작동"및 "새로 형성된 사본이 정렬 됨"이라고 말하지만 내부적으로 sort ()를 사용한다고 말하는 것은 아닙니다.
sundar-Monica 복원

형성되는 "복사본"은 목록 (반환 값으로 얻는 것임)이며, 반환하기 전에 해당 목록에서 .sort ()가 호출됩니다. QED. 아니오, 그것은 절대로 증명할 수없는 증거는 아니지만, 파이썬이 공식 표준을 가질 때까지 여러분은 그것을 얻지 못할 것입니다.
Peter Hansen

0

정렬에 관한 Python 3.6 문서는 이제 다음과 같이 말합니다.

정렬은 안정적이어야합니다.

또한,이 문서에서, 안정에 대한 링크가 Timsort 한다고,

Timsort는 버전 2.3부터 Python의 표준 정렬 알고리즘이었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.