- [BW 14] 복잡한 기준을 사용해 정렬할 때는 key 파라미터를 사용하라2024년 10월 22일
- 31514
- 작성자
- 2024.10.22.:11
다음과 같은 클래스가 있다고 가정해보고 tools 를 정의했다.
class Tool: def __init__(self, name, weight): self.name = name self.weight = weight def __repr__(self): return f'Tool({self.name!r}, {self.weight})' tools = [ Tool('수준계', 3.5), Tool('해머', 1.25), Tool('스크류드라이버', 0.25), Tool('끌', 0.25), ]
tools 에 담긴 여러 인스턴스를 sort()를 통해 정렬할 수 있을까?
비교 연산자를 지원하지 않는 오류가 발생한다.
Traceback (most recent call last): File "/Users/dev/Study/devcourse_aws/test.py", line 18, in <module> tools.sort() TypeError: '<' not supported between instances of 'Tool' and 'Tool'
하지만 정렬 기준으로 객체의 속성을 전달한다면 비교 가능하다.
tools.sort(key=lambda x: x.name) print(tools) >>> [Tool('끌', 0.25), Tool('수준계', 3.5), Tool('스크류드라이버', 0.25), Tool('해머', 1.25)]
만약 여러 기준을 사용해 정렬해야 한다면 어떻게 해야할까?
튜플을 사용하면 가장 쉽게 할 수 있다.
drill = (4, '드릴') hammer = (4, '해머') print(drill < hammer) >>> True
튜플을 활용하면 다음과 같이 sort 에도 적용할 수 있다.
tools.sort(key=lambda x: (x.weight, x.name)) print(tools) >>> [Tool('끌', 0.25), Tool('스크류드라이버', 0.25), Tool('해머', 1.25), Tool('수준계', 3.5)]
한 가지 제약 사항은 모든 비교 기준의 정렬 순서가 같아야 한다는 점이다.
예를 들어, x.weight에만 reverse를 걸 수 없다.
reverse를 걸면 x.weight과 x.name 모두 걸린다.
tools.sort(key=lambda x: (x.weight, x.name), reverse=True) print(tools) >>> [Tool('수준계', 3.5), Tool('해머', 1.25), Tool('스크류드라이버', 0.25), Tool('끌', 0.25)]
x.weight에만 reverse를 걸고 싶다면 두 가지 방법이 있다.
첫 번째는 x.weight이 숫자이므로 부호 반전을 사용하는 것이다.
tools.sort(key=lambda x: (-x.weight, x.name)) print(tools) >>> [Tool('수준계', 3.5), Tool('해머', 1.25), Tool('끌', 0.25), Tool('스크류드라이버', 0.25)]
두 번째는 파이썬이 제공하는 안정적인 정렬 알고리즘을 사용하는 것이다.
리스트 타입의 sort 메서드는 key 함수가 반환하는 값이 서로 같은 경우 리스트에 들어 있던 원래의 순서를 그대로 유지한다.
tools.sort(key=lambda x: x.name) tools.sort(key=lambda x: x.weight, reverse=True) print(tools) >>> [Tool('수준계', 3.5), Tool('해머', 1.25), Tool('끌', 0.25), Tool('스크류드라이버', 0.25)]
하지만 부호 반전을 사용할 수 있다면 가독성을 위해 선호한다.
'Book > 파이썬 코딩의 기술' 카테고리의 다른 글
[BW 19] 함수가 여러 값을 반환하는 경우 절대로 네 값 이상을 언패킹하지 말라 (0) 2024.10.22 [BW 18] __missing__을 사용해 키에 따라 다른 디폴트 값을 생성하는 방법 (0) 2024.10.22 [BW 13] 슬라이싱보다는 나머지를 모두 잡아내는 언패킹을 사용하라 (0) 2024.10.22 [BW 12] 스트라이드와 슬라이스를 한 식에 함께 사용하지 말라 (0) 2024.10.22 [BW 11] 시퀀스를 슬라이싱하는 방법을 익혀라 (0) 2024.10.22 다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)