1. sorted() 함수
- `iterable 객체(리스트, 튜플, 문자열 등)`를 정렬하여 `정렬된 새로운 리스트`를 반환하는 내장 함수.
- 쉽게 말해, `iterable`를 받아서 `list`를 반환함.
문법
result = sorted(iterable, key=None, reverse=False)
매개변수
1. iterable (필수)
- 정렬 대상이 되는 iterable 객체.
- ex. `str, list, tuple, dict의 key 등`
2. key (선택, 기본값 : None)
- 정렬 기준을 지정하는 함수.
- 각 요소에 대해 `key`로 전달된 함수가 호출되며, 반환된 값이 정렬 기준이 됨.
- 기본값은 `None`로 이 경우 요소 자체를 기준으로 정렬.
3. reverse (선택, 기본값 : False)
- 정렬 순서를 지정하는 bool 값.
- `reverse = True`로 설정하면 내림차순으로 정렬됨.
- 기본값은 `False`로, 이 경우 오름차순 정렬이 수행됨.
반환값
- `정렬된 새로운 리스트`가 반횐됨.
- 원본 데이터는 변경되지 않음.
예시
1. 기본 예시
sorted([3, 1, 2]) # [1, 2, 3]
sorted("hello") # ['e', 'h', 'l', 'l', 'o']
2. key 사용
# 기본 정렬 (요소 자체를 기준으로 오름차순)
sorted([3, 1, 2]) # [1, 2, 3]
# 정렬 기준을 절댓값으로 설정
sorted([-5, 3, -2, 7], key=abs) # [-2, 3, -5, 7]
# 문자열 길이 기준으로 정렬
words = ["apple", "kiwi", "banana"]
sorted(words, key=len) # ['kiwi', 'apple', 'banana']
# 이는 각각 람다 표현식으로 이렇게도 표현 가능함.
sorted([-5, 3, -2, 7], key=lambda x : abs(x)) # [-2, 3, -5, 7]
words = ["apple", "kiwi", "banana"]
sorted(words, key= lambda x : len(x)) # ['kiwi', 'apple', 'banana']
3. reverse 사용
# 내림차순 정렬
sorted([3, 1, 2], reverse=True) # [3, 2, 1]
# 길이 기준으로 내림차순 정렬
words = ["apple", "kiwi", "banana"]
sorted(words, key=len, reverse=True) # ['banana', 'apple', 'kiwi']
4. 반환값
nums = [3, 1, 4]
result = sorted(nums)
print(nums) # [3, 1, 4] (원본 유지)
print(result) # [1, 3, 4] (정렬된 새로운 리스트)
5. key에 사용자 지정 함수 사용
1. 절댓값 기준으로 정렬
def by_absolute_value(x):
return abs(x)
nums = [-5, 3, -2, 7]
result = sorted(nums, key=by_absolute_value)
print(result) # [-2, 3, -5, 7]
2. 문자열 길이 기준으로 정렬
def by_length(word):
return len(word)
words = ["apple", "kiwi", "banana"]
result = sorted(words, key=by_length)
print(result) # ['kiwi', 'apple', 'banana']
6. key에 람다 표현식 사용
위에서 살펴본 함수를 람다 표현식을 사용하면 각각 아래와 같음.
1. 절댓값 기준으로 정렬
nums = [-5, 3, -2, 7]
result = sorted(nums, key=lambda x: abs(x))
print(result) # [-2, 3, -5, 7]
# 참고로 이는, 아까 그냥 key = abs 로 한 것과 같음.
2. 문자열 길이 기준으로 정렬
words = ["apple", "kiwi", "banana"]
result = sorted(words, key=lambda word: len(word))
print(result) # ['kiwi', 'apple', 'banana']
# 참고로 이는, 아까 그냥 key = len 로 한 것과 같음.
7. 기타 예시
1. 튜플의 두 번째 요소를 기준으로 정렬하되, 값이 같으면 첫 번째 요소를 기준으로 정렬
data = [(1, 3), (4, 1), (2, 2), (3, 1)]
result = sorted(data, key=lambda x: (x[1], x[0]))
print(result) # [(3, 1), (4, 1), (2, 2), (1, 3)]
두 개 이상의 기준으로 정렬하는 예시였음.
-> 즉, key에 사용하는 (람다) 함수의 반환값이 튜플 형태
2. 대소문자 구분 없이 문자열 정렬
words = ["Banana", "apple", "Cherry"]
result = sorted(words, key=lambda word: word.lower())
print(result) # ['apple', 'Banana', 'Cherry']
3. 학생 점수 정렬 : 총점 기준, 동점자는 이름순
students = [
{"name": "Alice", "math": 85, "english": 92},
{"name": "Bob", "math": 75, "english": 88},
{"name": "Charlie", "math": 85, "english": 90},
]
# 정렬
result = sorted(
students,
key=lambda student: (student["math"] + student["english"], student["name"]),
reverse=True,
)
print(result)
# [{'name': 'Charlie', 'math': 85, 'english': 90},
# {'name': 'Alice', 'math': 85, 'english': 92},
# {'name': 'Bob', 'math': 75, 'english': 88}]
8. sorted()는 안정 정렬(stable sort)
- sorted()는 내부적으로 Tim sort로 구현되는데, 이는 stable sort이기에
- 비교 기준이 모두 같으면, 원래의 순서대로 정렬됨.
- 즉, 같은 우선순위를 가지는 것 끼리는 기존의 정렬 순서를 유지함.
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)`이 원래의 순서를 유지함.
a = ['cde', 'cfc', 'abc', 'czc', 'cac']
result = sorted(a, key = lambda s:(s[0], s[-1]))
print(result) # ['abc', 'cfc', 'czc', 'cac', 'cde']
`'cfc', 'czc', 'cac' 끼리는 원래의 순서를 유지함.
https://cuffyluv.tistory.com/125
자세한 건 위에 정리한 글 참고.
2. list.sort()
- 리스트 원본 자체를 정렬해 변경하는 리스트 내장 메서드.
- 쉽게 말해, `list`를 받아서 그 자체를 변경함.
문법
list.sort(key=None, reverse=False)
매개변수
1. key (선택, 기본값 : None)
- 정렬 기준을 지정하는 함수.
- 각 요소에 대해 `key`로 전달된 함수가 호출되며, 반환된 값이 정렬 기준이 됨.
- 기본값은 `None`로 이 경우 요소 자체를 기준으로 정렬.
2. reverse (선택, 기본값 : False)
- 정렬 순서를 지정하는 bool 값.
- `reverse = True`로 설정하면 내림차순으로 정렬됨.
- 기본값은 `False`로, 이 경우 오름차순 정렬이 수행됨.
반환값
- 중요!! list.sort()는 반환값이 없음 (반환값 : None)
- 원본 데이터인 리스트가 직접 변경됨.
예시
1. 기본 예시
nums = [3, 1, 2]
nums.sort()
print(nums) # [1, 2, 3] (원본 리스트가 정렬됨)
2. key 사용
nums = [-5, 3, -2, 7]
nums.sort(key=abs)
print(nums) # [-2, 3, -5, 7] (절댓값 기준으로 정렬됨)
words = ["apple", "kiwi", "banana"]
words.sort(key=len)
print(words) # ['kiwi', 'apple', 'banana'] (길이 기준으로 정렬됨)
3. reverse 사용
nums = [3, 1, 2]
nums.sort(reverse=True)
print(nums) # [3, 2, 1] (내림차순 정렬됨)
words = ["apple", "kiwi", "banana"]
words.sort(key=len, reverse=True)
print(words) # ['banana', 'apple', 'kiwi'] (길이 기준으로 내림차순 정렬됨)
4. key에 사용자 지정 함수 사용
1. 절댓값 기준으로 정렬
def by_absolute_value(x):
return abs(x)
nums = [-5, 3, -2, 7]
nums.sort(key=by_absolute_value)
print(nums) # [-2, 3, -5, 7]
2. 문자열 길이 기준으로 정렬
def by_length(word):
return len(word)
words = ["apple", "kiwi", "banana"]
words.sort(key=by_length)
print(words) # ['kiwi', 'apple', 'banana']
5. key에 람다 표현식 사용
위에서 살펴본 함수를 람다 표현식을 사용하면 각각 아래와 같음.
1. 절댓값 기준으로 정렬
nums = [-5, 3, -2, 7]
nums.sort(key=lambda x: abs(x))
print(nums) # [-2, 3, -5, 7]
# 참고로 이는, 아까 그냥 key = abs 로 한 것과 같음.
2. 문자열 길이 기준으로 정렬
words = ["apple", "kiwi", "banana"]
words.sort(key=lambda word: len(word))
print(words) # ['kiwi', 'apple', 'banana']
# 참고로 이는, 아까 그냥 key = len 로 한 것과 같음.
6. 기타 예시
1. 튜플의 두 번째 요소를 기준으로 정렬하되, 값이 같으면 첫 번째 요소를 기준으로 정렬
data = [(1, 3), (4, 1), (2, 2), (3, 1)]
data.sort(key=lambda x: (x[1], x[0]))
print(data) # [(3, 1), (4, 1), (2, 2), (1, 3)]
두 개 이상의 기준으로 정렬하는 예시였음.
-> 즉, key에 사용하는 (람다) 함수의 반환값이 튜플 형태
2. 대소문자 구분 없이 문자열 정렬
words = ["Banana", "apple", "Cherry"]
words.sort(key=lambda word: word.lower())
print(words) # ['apple', 'Banana', 'Cherry']
3. 학생 점수 정렬 : 총점 기준, 동점자는 이름순
students = [
{"name": "Alice", "math": 85, "english": 92},
{"name": "Bob", "math": 75, "english": 88},
{"name": "Charlie", "math": 85, "english": 90},
]
# 정렬
students.sort(
key=lambda student: (student["math"] + student["english"], student["name"]),
reverse=True,
)
print(students)
# [{'name': 'Charlie', 'math': 85, 'english': 90},
# {'name': 'Alice', 'math': 85, 'english': 92},
# {'name': 'Bob', 'math': 75, 'english': 88}]
8. sorted()는 안정 정렬(stable sort)
- sorted()는 내부적으로 Tim sort로 구현되는데, 이는 stable sort이기에
- 비교 기준이 모두 같으면, 원래의 순서대로 정렬됨.
- 즉, 정렬 기준이 모두 동일한 요소들은 원래의 순서를 유지함.
data = [(1, 3, 5, 7, 9), (1, 3, 2, 4, 8), (2, 2, 3, 6, 7), (3, 1, 6, 8, 10)]
data.sort(key=lambda x: (x[1], x[0]))
print(data) # [(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)`이 원래의 순서를 유지함.
a = ['cde', 'cfc', 'abc', 'czc', 'cac']
a.sort(a, key = lambda s:(s[0], s[-1]))
print(a) # ['abc', 'cfc', 'czc', 'cac', 'cde']
`'cfc', 'czc', 'cac' 끼리는 원래의 순서를 유지함.
3. 정리 및 비교
- 여태 예시들을 보면 알겠지만, 변경할 대상을 첫 매개변수로 쓰냐 아님 메서드의 주체로 쓰냐의 차이지,
- 그 외에 사용 방법이나 테크닉 등은 모두 동일함.
- 그러나, 일부 차이점이 있는데
- `sorted()`는 원본 객체를 변경하지 않으며, 새로운 리스트를 반환함.
- `list.sort()`는 리스트 자체를 변경하며 반환값이 없음.
=> 둘 다 결국 변환된 결과가 리스트라는 것은 똑같다고 볼 수 있음.
- `sorted()`는 `iterable 객체`라면 모두 사용이 가능하나,
- `list.sort()`는 (리스트의 메서드니까 당연히) `list`에만 사용 가능함.
- 상황에 맞게 사용하면 될 듯한데,
- 아마 대부분의 상황에서 sorted()를 사용하게 되지 않을까?
- 왜냐면 굳이 원본 리스트를 변경할 필요는 없어보임.
- 원본 리스트는 보험으로 남겨두는 편이 대부분 좋을 테니까.
Ref.
https://daeun-computer-uneasy.tistory.com/74
https://yummy0102.tistory.com/683
- Chat GPT
'Programming > Python' 카테고리의 다른 글
[Python] 문자열 치환 메서드 성능 비교 - str.replace(), re.sub(), str.translate() (0) | 2025.01.24 |
---|---|
[Python] import문 사용법(패키지, 모듈 차이) (0) | 2024.08.17 |