이문제를 풀다가 알게된 새로운함수 python내용
list.sort() 의 key 파라미터로 lambda 함수를 넘겨 주어, element의 정렬 조건을 설정했다.
그러니까 lambda에 정렬기준을 '직접' 입력한 것이다.
예를들어 튜플의 1번째 글자를 기준으로 내림차순 정렬한다고 하면 이렇게 x[1]을 정렬기준으로 지정해줬다.
arr = [(1, 2), (2, 3), (1, 3), (2, 4), (3, 4)]
arr.sort(key=lambda x: x[1], reverse=True) # 튜플 1번째 값으로 정렬
print(arr)
앞서 한번 정리한적있다. lambda로 sort하는 방법.
https://pearlluck.tistory.com/462
하지만, 이렇게 lambda로 정렬기준을 콕집어낼 수 없을 경우는?
그러니까 어떤경우에는 앞으로 가서 정렬하고, 어떤경우에는 뒤로 보내서 정렬하고, 어떤경우에는 제자리게 있도록.
이렇게 커스텀한 정렬기준을 가지고 정렬을 할 수 있는 방법이 있다.
python 공식문서에도 나와있는 cmp매개변수를 사용하는 방법이다
list.sort()를 수행할때, key 파라미터로 functools.cmp_to_key(함수명)을 넘겨주는 것이다.
python3의 경우 cmp파라미터 대신 cmp_to_key파라미터를 사용한다.
보통 아래와 같은 조건일때 cmp파라미터를 사용한 커스텀정렬방식을 자주사용한다.
lambda로 정렬하는 기준과 다르게 정렬기준이 2개이상이다.
좌표를 y좌표가 증가하는 순으로, y좌표가 같으면 x좌표가 증가하는 순서로 정렬 >>문제출처 : 백준
위와 같이 lambda로 정렬을 한 내용을 cmp매개변수를 사용해서 아래처럼 수정할 수 있다.
커스텀한 정렬기준을 만드는 함수 xy_compare를 직접 만들어주는 것이다.
이때, 리턴값은 항상 1,-1,0 이여야한다.
1은 정렬기준대로 앞으로 가기 위해 True를 의미하고,
-1은 정렬기준과 반대로 가서 뒤로가기 위해 False를 의미하고,
0은 아예 정렬기준에 해당하지 않아 그대로 있을때를 의미한다.
from functools import cmp_to_key # cmp_to_key가 필요한 경우 import
def xy_compare(a, b):
if a[1] > b[1]: # y좌표가 작은 것부터 앞으로 가게 정렬
return 1
elif a[1] == b[1]: # y좌표가 같을 경우
if a[0] > b[0]: # x 좌표가 작은 것부터 앞으로 가게 정렬
return 1
elif a[0] < b[0]: # x 좌표가 큰 것은 뒤로 가게
return -1
else: # 같은 경우에는 그대로
return 0
else: # y좌표가 큰 것이 뒤로 가게
return -1
xy_lst = sorted(xy_lst, key=cmp_to_key(xy_compare))
앗, 이걸 알기전에 나는 그저 좌표값이라 2개니까 람다에 기준 2개(x,y) 직접 지정했었다;;;물론이게 편하니까
num.sort(key=lambda x:(x[1],x[0]))
추가로 한가지 더 살펴보면 해커랭크의 문제는
이름과 성적을 정렬하는 것이였따.
이름이 증가하는 순으로 정렬하고, 점수가 같으면 이름이 증가하는 순서로 정렬 >>문제출처 : 해커랭크
def comparator(a, b):
if a.score == b.score: #점수가 같으면
if a.name>b.name: #name이 큰 순서대로
return 1
else: #name이 작은 순서는 반대
return -1
else: #점수가 다르면, 점수가 큰 순서대로
return b.score-a.score
data = sorted(data, key=cmp_to_key(Player.comparator))
for i in data:
print(i.name, i.score)
출처
https://justkode.kr/python/pygorithm-3
'🍃 Language > Python' 카테고리의 다른 글
[python] Django에서 절대경로 __file__ 로 지정하기 (os.path) (2) | 2021.09.06 |
---|---|
[Python] Dict로 문자열 count하기 | setDefault(i,0), get(i,0) (0) | 2021.07.12 |
[Python] 문자열 애너그램(Anagrams) | Counter(), DefaultDict() (0) | 2021.07.12 |
[python] 대문자로 변환하기 upper() / capitalize() / title() (0) | 2021.07.11 |
[python] 정규표현식과 Re모듈함수(match/search/findall/fullmatch) (0) | 2021.07.05 |
[python] String을 식으로 반환해주는 eval() 함수 (0) | 2021.06.22 |