숫자 세 개를 정렬해 ordered에 담았는데 값이 None이다. 정렬이 실패했나 싶어 원래 리스트를 보면, 그쪽은 이미 가지런하다. 결과가 사라진 게 아니라 정렬한 자리와 반환값을 혼동한 것이다.
list.sort()는 왜 None을 반환할까?
list.sort()는 새 리스트를 만드는 대신 기존 리스트의 순서를 직접 바꾼다. 그래서 반환값을 정렬된 리스트로 쓰면 안 된다.
도식은 원본 변경 여부와 반환값을 따로 보여 준다. 같은 리스트에 sort()와 sorted()를 적용해 원본과 결과를 함께 출력해 보자.
jobs = [3, 1, 2]
ordered = jobs.sort()
print(ordered) # None
print(jobs) # [1, 2, 3]이 상태에서 for job in ordered:를 실행하면 TypeError: 'NoneType' object is not iterable이 난다. 리스트가 비어서가 아니라 ordered가 리스트가 아니기 때문이다. 원본을 바꾸는 게 목적이라면 결과를 다른 변수에 담지 말고 jobs.sort()만 호출한 뒤 jobs를 사용한다.
sorted()를 쓰면 원본도 바뀔까?
원본 순서를 남겨야 한다면 sorted()를 사용한다. 반환된 새 리스트를 변수에 담고, 원래 리스트는 그대로 둔다.
jobs = [3, 1, 2]
ordered = sorted(jobs)
print(jobs) # [3, 1, 2]
print(ordered) # [1, 2, 3]sort()와 sorted()의 차이는 이름보다 누가 바뀌는지로 기억하면 쉽다. jobs.sort()는 jobs를 바꾸고, sorted(jobs)는 정렬된 다른 리스트를 돌려준다.
원본을 바꿔도 되는지 어떻게 결정할까?
다른 코드도 같은 리스트를 쓰고 있다면 원본 변경이 예상 밖의 결과를 만들 수 있다.
jobs = [3, 1, 2]
pending = jobs
jobs.sort()
print(pending) # [1, 2, 3]pending은 복사본이 아니라 같은 리스트를 가리킨다. 원본 정렬이 의도라면 sort(), 입력 순서를 보존하거나 정렬된 결과를 따로 전달해야 한다면 sorted()를 고른다. 어느 쪽이든 반환값과 원본을 함께 확인하면 None이 나온 이유를 금방 찾을 수 있다.
핵심 요약
list.sort()는 리스트를 제자리에서 정렬하고 None을 반환한다. sorted()는 원본을 그대로 두고 정렬된 새 리스트를 반환한다. 정렬 결과를 변수에 담으려면 ordered = sorted(jobs), 원본을 바꾸려면 jobs.sort()라고 쓰면 된다.

