`sorted (list)`와`list.sort ()`의 차이점은 무엇입니까?


194

list.sort()목록을 정렬하고 원본 목록을 바꾸는 반면 원본 목록 sorted(list)을 변경하지 않고 목록의 정렬 된 사본을 반환합니다.

  • 언제 다른 하나보다 선호됩니까?
  • 어느 것이 더 효율적입니까? 얼마만큼?
  • 목록을 list.sort()수행 한 후 정렬되지 않은 상태로 되돌릴 수 있습니까 ?

4
만약 당신이 (실수로) 호출을 조심 sorted()문자열 인수에 있지만, 당신은 목록 결과를 목록 얻을 생각하지 문자열 : sorted("abcd", reverse=True)제공 ['d', 'c', 'b', 'a']하지"dcba"
SMCI

답변:


317

sorted() 정렬 된 목록을 반환 하고 원래 목록은 영향을받지 않습니다. list.sort()리스트를 in-place 정렬하고리스트 인덱스를 변경하고 None모든 in-place 조작과 같이 리턴합니다 .

sorted()목록뿐만 아니라 반복 가능한 작업에서도 작동합니다. 문자열, 튜플, 사전 (키를 얻음), 생성기 등 모든 요소가 포함 된 목록을 정렬하여 반환합니다.

  • 정렬 된 새 객체를 원할 때 list.sort()목록을 변경하려는 경우에 사용하십시오 sorted(). 사용 sorted()당신은 반복 가능한 아닌 목록 무언가 정렬 할 때 이 아직 없습니다 .

  • 목록의 경우 사본을 만들 필요가 없으므로 list.sort()보다 빠릅니다 sorted(). 다른 iterable의 경우 선택의 여지가 없습니다.

  • 아니요, 원래 위치를 검색 할 수 없습니다. 당신 list.sort()이 원래 주문 을 호출 하면 사라집니다.


6
일반적으로 python 함수가을 반환 None하면 작업이 제대로 수행되었다는 신호이므로 인쇄하려는 경우 list.sort()없음을 반환합니다.
user1767754

45

의 차이 무엇입니까 sorted(list)대는 list.sort()?

  • list.sort 현재 위치에서 목록을 변경하고 리턴 None
  • sorted iterable을 취하고 정렬 된 새 목록을 리턴합니다.

sorted 이 Python 구현과 동일하지만 CPython 내장 함수는 C로 작성 될 때 측정 속도가 훨씬 빠릅니다.

def sorted(iterable, key=None):
    new_list = list(iterable)    # make a new list
    new_list.sort(key=key)       # sort it
    return new_list              # return it

언제 사용합니까?

  • 사용 list.sort원래 정렬 순서를 유지하지 않으려는 경우 (따라서 당신은. 메모리에 현재 위치에서 목록을 다시 사용할 수있을 것입니다) 당신은 (목록의 유일한 소유자 인 경우 목록은 다른 코드와 공유하는 경우 변경하면 해당 목록이 사용되는 버그가 발생할 수 있습니다.)
  • 사용 sorted원래 정렬 순서를 유지하려는 경우 또는 당신은 당신의 지역 코드가 소유 새로운 목록을 작성하고자 할 때.

list.sort () 이후에 목록의 원래 위치를 검색 할 수 있습니까?

아니요-직접 복사하지 않으면 정렬이 완료되어 해당 정보가 손실됩니다.

"그리고 어느 것이 더 빠릅니까? 그리고 얼마나 더 빠릅니까?"

새 목록을 만드는 데 따른 불이익을 설명하기 위해 timeit 모듈을 사용하십시오. 설정은 다음과 같습니다.

import timeit
setup = """
import random
lists = [list(range(10000)) for _ in range(1000)]  # list of lists
for l in lists:
    random.shuffle(l) # shuffle each list
shuffled_iter = iter(lists) # wrap as iterator so next() yields one at a time
"""

그리고 여기 무작위로 배열 된 10000 개의 정수 목록에 대한 결과가 있습니다. 여기에서 볼 수 있듯이, 우리는 오래된 목록 작성 비용 신화를 반증 했습니다 .

파이썬 2.7

>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[3.75168503401801, 3.7473005310166627, 3.753129180986434]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[3.702025591977872, 3.709248117986135, 3.71071034099441]

파이썬 3

>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[2.797430992126465, 2.796825885772705, 2.7744789123535156]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[2.675589084625244, 2.8019039630889893, 2.849375009536743]

피드백을받은 후에 다른 특성을 가진 다른 테스트가 바람직하다고 결정했습니다. 여기에서는 각 반복에 대해 길이가 100,000 배인 동일한 무작위 순서의 목록을 1,000 번 제공합니다.

import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""

나는 Martijn이 언급 한 복사에서 오는이 더 큰 종류의 차이점을 해석하지만, 여기에서 더 오래된 더 인기있는 답변에 언급 된 지점까지 지배하지 않습니다. 여기서 시간의 증가는 약 10 %입니다

>>> timeit.repeat("lst[:].sort()", setup=setup, number = 10000)
[572.919036605, 573.1384446719999, 568.5923951]
>>> timeit.repeat("sorted(lst[:])", setup=setup, number = 10000)
[647.0584738299999, 653.4040515829997, 657.9457361929999]

나는 또한 훨씬 더 작은 정렬에서 위를 실행했으며 새로운 sorted사본 버전은 여전히 ​​1000 길이의 정렬에서 약 2 % 더 오래 실행되는 시간을 보았습니다 .

Poke는 자신의 코드도 실행했습니다. 코드는 다음과 같습니다.

setup = '''
import random
random.seed(12122353453462456)
lst = list(range({length}))
random.shuffle(lst)
lists = [lst[:] for _ in range({repeats})]
it = iter(lists)
'''
t1 = 'l = next(it); l.sort()'
t2 = 'l = next(it); sorted(l)'
length = 10 ** 7
repeats = 10 ** 2
print(length, repeats)
for t in t1, t2:
    print(t)
    print(timeit(t, setup=setup.format(length=length, repeats=repeats), number=repeats))

그는 1000000 길이 정렬, 비슷한 결과를 얻었지만 (약 100 배) 시간이 약 5 % 증가한 결과는 다음과 같습니다.

10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655

결론:

sorted사본 을 만들 때 정렬되는 큰 크기의 목록은 차이를 지배하지만 정렬 자체가 작업을 지배하며 이러한 차이를 중심으로 코드를 구성하면 조기 최적화됩니다. 내가 사용하는 것이 sorted내가 데이터의 새로운 정렬 된 목록을 필요로 할 때, 내가 사용하는 것이 list.sort내가 현재 위치에서 목록을 정렬 할 필요가있을 때, 그리고 내 사용을 결정할 수 있습니다.


4
발전기 설정은 훌륭하지만, 당신이 신화를 너무 빨리 파괴했다는 결론을 내리지는 않을 것입니다. sorted()새로운리스트 객체를 할당하고 참조를 복사해야 한다는 사실이 남아 있습니다 . 나머지 코드 경로는 동일합니다. 더 큰 목록으로 동일한 테스트를 실행할 수 있는지 확인하십시오. 리스트 사본 만 작성하여 비교하고 발견 한 차이점 등을 복제 할 수 있는지 확인하십시오.
Martijn Pieters

11

주요 차이점은 새로운 것을 sorted(some_list)반환한다는 것입니다 .list

a = [3, 2, 1]
print sorted(a) # new list
print a         # is not modified

some_list.sort(), 목록 을 제자리에 정렬합니다 .

a = [3, 2, 1]
print a.sort() # in place
print a         # it's modified

부터 것을 a.sort()아무것도 반환하지 않습니다 print a.sort()인쇄됩니다 None.


list.sort () 후에 목록 원래 위치를 검색 할 수 있습니까?

아니요, 원래 목록을 수정하기 때문입니다.


1
print a.sort()아무것도 인쇄하지 않습니다.
Burhan Khalid

1
인쇄 None할 것입니다.
Christian

1

.sort () 함수는 새 변수 값을 목록 변수에 직접 저장합니다. 세 번째 질문에 대한 답은 아니오입니다. 또한 sorted (list)를 사용 하여이 작업을 수행하면 목록 변수에 저장되지 않기 때문에 사용할 수 있습니다. 또한 때때로 .sort () 메소드는 함수로 작동하거나 인수를 취한다고 말합니다.

sorted (list) 값을 변수에 명시 적으로 저장해야합니다.

또한 짧은 데이터 처리의 경우 속도에는 차이가 없습니다. 그러나 긴 목록을 위해; 빠른 작업을 위해서는 .sort () 메소드를 직접 사용해야합니다. 그러나 다시 돌이킬 수없는 행동에 직면하게됩니다.


".sort () 함수는리스트 변수에 새로운리스트의 값을 직접 저장합니다"Huh? 새로운 목록은 무엇입니까? 새로운 목록이 없습니다. 이 list.sort()메소드는 목록 오브젝트를 제자리에서 정렬합니다.
오후 2시

또한 이것이 무엇을 의미합니까? "때때로 .sort () 메소드는 함수의 역할을하거나 인수를받는다고 말합니다."
오후 2시

새 목록의 의미는 수정 된 목록이며 .sort ()는 수정 된 목록을 동일한 변수에 저장합니다.
Vicrobot

그렇습니다. 절대적으로 .sort()메소드는 인수를 취하고 함수로 작동합니다. 또한 목록 데이터 유형의 속성이므로 메소드라고합니다.
Vicrobot

내 개념에 어떤 종류의 실수가 있다면 말해, 나는 그것을 찾아 내 개념을 개선하고 내 대답도 향상시킬 것입니다. 감사합니다
Vicrobot

1

다음은 동작의 차이점을 보여주는 몇 가지 간단한 예입니다.

여기에서 숫자 목록을보십시오 :

nums = [1, 9, -3, 4, 8, 5, 7, 14]

호출 할 때 sorted이 목록에, sorteda를한다 사본 목록을. (원래 목록을 의미하는 것은 변경되지 않습니다.)

보자

sorted(nums)

보고

[-3, 1, 4, 5, 7, 8, 9, 14]

상기 찾고 nums다시

nums

원래 목록 (변경되지 않고 정렬되지 않음)이 표시됩니다. sorted원래 목록을 변경하지 않았습니다

[1, 2, -3, 4, 8, 5, 7, 14]

동일한 nums목록을 가져 sort와서 기능을 적용 하면 실제 목록이 변경됩니다.

보자

nums목록에서 시작 하여 내용은 여전히 ​​동일합니다.

nums

[-3, 1, 4, 5, 7, 8, 9, 14]

nums.sort()

이제 원래 숫자 목록이 변경되고 원래 목록이 변경되어 정렬 된 숫자를 살펴 봅니다.

nums
[-3, 1, 2, 4, 5, 7, 8, 14]

원본과 사본을 더 깊이 보여 주셔서 감사합니다
Brendan Metcalfe

0

참고 : sort ()와 sorted ()의 가장 간단한 차이점은 다음과 같습니다. sort ()는 값을 반환하지 않지만 sorted ()는 반복 가능한 목록을 반환합니다.

sort ()는 어떤 값도 반환하지 않습니다.

sort () 메서드는 주어진 목록의 요소를 값을 반환하지 않고 오름차순 또는 내림차순으로 특정 순서로 정렬합니다.

sort () 메소드의 구문은 다음과 같습니다.

list.sort(key=..., reverse=...)

또는 동일한 목적으로 Python의 내장 함수 sorted ()를 사용할 수도 있습니다. 정렬 된 함수 반환 정렬 된 목록

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