일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 티스토리챌린지
- githubactions
- 오블완
- 도커
- 백준
- 스프링
- java
- yaml-resource-bundle
- springsecurity
- 리프레시토큰
- JIRA
- 액세스토큰
- 파이썬
- docker
- 스프링시큐리티
- AWS
- 국제화
- oauth2
- 재갱신
- 스프링부트
- Spring
- CI/CD
- 데이터베이스
- 토이프로젝트
- 트랜잭션
- 메시지
- springdataredis
- 소셜로그인
- springsecurityoauth2client
- 프로그래머스
- Today
- Total
땃쥐네
[Python] 파이썬 리스트 정렬 본문
리스트.sort() 를 통한 정렬 : 원본 리스트 상태 변경
def my_sort_func(x):
return x
array = [1,3,7,9,6,8,5,2,4]
array.sort(key=my_sort_func) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(array) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
기본적으로 파이썬은 리스트에 대해서 sort 함수를 제공한다.
sort 함수는 key 를 통해 정렬 기준을 만드는 함수를 지정하고 이에 따라 정렬을 할 수 있다.
기본적으로는 오름차순 정렬을 한다.
예를 들어 위의 my_sort_func 은 x 가 전달되면 x를 반환하는데 이 값이 작을 수록 정렬 시 좀 더 앞서게 된다.
여기서 작다는 말은 숫자 관점에서는 숫자 오름차순 정렬 기준 앞선다는 것을 의미하고, 문자열 관점 역시 문자열 오름차순 정렬 기준이라 보면 된다.
1 과 9 를 비교하면 1이 더 작으므로, 1이 더 앞선다.
'a' 와 'bcd' 를 비교하면 'a'가 사전순으로 앞서므로(작으므로) 'a'가 더 앞선다.
array = [1,3,7,9,6,8,5,2,4]
array.sort(key=lambda x: x) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(array) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
key 로는 직접 함수를 전달하지 않고, lambda 를 통해 간소화시킬 수 있다.
array = [1,3,7,9,6,8,5,2,4]
array.sort(key=lambda x: x, reverse=True) # [9, 8, 7, 6, 5, 4, 3, 2, 1]
print(array) # [9, 8, 7, 6, 5, 4, 3, 2, 1]
추가로, reverse 파라미터를 통해 역순 정렬을 할 것인지 추가로 지정할 수 있다.
앞의 key 를 통해 정렬을 하는데 reverse 가 추가로 적용되면 역순으로 정렬하게 된다.
sorted()를 통한 정렬 : 원본은 그대로 두고 정렬된 리스트 반환
array = [1,3,7,9,6,8,5,2,4]
array.sort(key=lambda x: x) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(array) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
array = [1,3,7,9,6,8,5,2,4]
sorted_array = sorted(array, key=lambda x: x)
print(sorted_array) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(array) # [1,3,7,9,6,8,5,2,4]
리스트 객체에 대해서, .sort() 메서드를 호출하면 그 리스트를 정렬되는데, 그 결과 리스트의 상태가 변경되는 부작용이 존재한다.
sorted 함수를 통해 리스트를 전달하면 정렬된 리스트를 반환하지만 원본 리스트의 상태를 변경시키지 않는다.
함수형 프로그래밍 관점에서는 함수가 전달된 객체의 상태를 변경시키는 것보다는, 새로운 객체를 반환하는 것이 유지보수성이 좋기 때문에 이 방식을 개인적으로 선호한다.
정렬의 우선순위 지정 방법
def my_sort_func(x):
# x가 문자열이라 할 때 문자열의 길이가 짧은 것을 우선 두고, 길이가 같으면 문자열 정렬 순으로
return len(x), x
array = ['c', 'abc', 'a', 'def']
print(sorted(array, key=my_sort_func)) # ['a', 'c', 'abc', 'def']
print(sorted(array, key=lambda x: (len(x), x))) # ['a', 'c', 'abc', 'def']
print(sorted(array, key=lambda x: (len(x), x), reverse=True)) # 역순 -> ['def', 'abc', 'c', 'a']
정렬 조건을 두가지 이상으로 지정하는 방법도 존재한다.
key 에 전달한 함수에서 튜플을 반환하게 하면 된다.
튜플의 첫번째 값이 작으면(앞서면) 맨 앞에 가고, 첫번째 값이 같으면 그 뒤의 요소를 기준으로 정렬한다.
참고로 튜플의 요소 수가 2개, 3개, ..., n개 순으로 가도 이와 비슷한 원리가 적용된다.
함수를 지정하지 않고 lambda 를 통해 간소화시킬 수도 있다.
(+ reverse 파라미터를 통해 key 의 정렬 기준을 역순으로 해서 정렬할 수도 있다.)
두 요소를 기준으로 한 정렬기준 설정
from functools import cmp_to_key
def compare(a, b):
if a < b:
return -1
elif a > b:
return 1
else:
return 0
array = [1,3,7,9,6,8,5,2,4]
sorted_array = sorted(array, key=cmp_to_key(compare))
print(sorted_array) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
또다른 방식으로는 두 요소 a,b가 주어졌을 때를 기준으로 정렬하는 방법이 존재한다.
(보통 python 초급 서적에서는 이 방식은 서술되지 않는다.)
변수 a, b 가 전달 됐을 때를 기준으로 음수/양수/0 을 반환하는 함수를 만든뒤
functools 의 cmp_to_key 함수로 전달하는 방식이다.
이 방식을 사용하면
음수를 반환하면 a 를 앞으로 보내고
양수를 반환하면 b 를 앞으로 보내며
0 을 반환하면 둘의 정렬 기준을 같게 만든다.
(Java 에 익숙한 입장에서는 이 방식이 좀 더 친숙하다.)
보통 python 스러운 코드를 작성할 때는 이 방식을 잘 사용하지 않지만 정렬 기준이 복잡한 경우 이 방식을 쓰면 좋은 경우가 있었다. (예: 프로그래머스 - 가장 큰 수)