sort 완벽 정복 !

About_work·2023년 1월 18일
0

python 기초

목록 보기
9/65

sort 메서드 & key parameter 을 쓰자.

  • sort 메서드는 자연스럽게 순서를 정할 수 있는 거의 대부분의 내장타입(str, float, list 등)에 잘 작동한다.
  • 하지만 아래와 같은 경우는 동작하지 않는다.
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.5),
    Tool('끌', 0.25),
]

tools.sort() >>> Tracback...
  • 위의 경우 sort를 위한 magic method (__lt__) 가 정의되지 않아서 생긴 에러인데, 여기서 magic method를 추가하기 보다는 sort의 key 파라미터 를 쓰는 것이 낫다.
    • 왜냐하면, 만든 객체가 여러 가지 순서를 지원해야하는 경우가 더 많기 때문이다.
  • key 파라미터에는 함수가 들어가야 하고, 함수의 argument에는 "정렬 중인 리스트의 원소"가 전달된다.
tools.sort(key=lambda x: x.name)
>>>
[Tool('끝', 0.25), Tool('수준계', 3.5), Tool('스크류드라이버', 0.5), Tool('해머', 1.25)]
  • 심지어 문자열 같은 기본 타입의 경우에는, 정렬하기 전에 key 함수를 이용해 원소 값을 변경한 채로 sort 할 수도 있다.
places = ['home', 'work', 'New York', 'Paris']
places.sort(key=lambda x: x.lower())
  • sort에 reverse parameter 도 쓸 수 있다. (내림차순 하고 싶으면 쓰자)
tools.sort(key=lambda x: x.name, reverse=True)

여러 기준으로 sort 하기

  • 여러 기준으로 sort하고 싶을 때? : tuple 로 비교하자!
    • 튜플은 튜플의 각 위치를 iteration 하면서, 각 index에 해당하는 원소를 한번에 하나씩 비교한다.
    • 즉, 튜플은 첫 번째 위치에 있는 값이 서로 같으면, 두 번째 위치에 있는 값을 비교한다.
drill = (4, '드릴')
sander = (4, '연마기')
power_tools.sort(key=lambda x: (x.weight, x.name)

assert drill[0] == sander[0] # 무게가 같다
assert drill[1] < sander[1]  # 알파벳순으로 볼 때 더 작다
assert drill < sander        # 그러므로 드릴이 더 먼저다
    • 단점
      • 튜플에 sort(key= ~~)를 쓰는 것의 단점은, 모든 비교 기준의 정렬 순서가 같아야 한다는 점(모두 오름차순이거나 모두 내림차순)
  power_tools.sort(key=lambda x: (x.weight, x.name),
                 reverse=True) # 모든 비교 기준을 내림차순으로 만든다
    • 어떤 기준은 오름차순, 어떤 기준은 내림차순으로 하고 싶으면??
    • 방법 1
      • minus 를 붙여라.
      • (방법 1로 해결되면 방법2 말고 1을 쓰는 것을 권장한다.)
      • 코드가 더 적고 읽기도 쉽기 때문이다.
power_tools.sort(key=lambda x: (-x.weight, x.name))
print(power_tools)
    • 방법 2
      • 위 예시에서, x.name 같은 경우는 minus 등을 붙일 수 없다.
      • 아래 예제는, weight 순서로 먼저 정렬한 후, 그 다음 동점자에 대해 name으로 정렬 하고 싶은 경우이다. (코드의 순서는 반대로 된다.)
      • 리스트 타입의 sort 메서드는, key 함수가 반환하는 값이 서로 같은 경우, 리스트에 들어 있던 원래 순서를 그대로 유지해준다.
power_tools.sort(key=lambda x: x.name)   # name 기준 오름차순
power_tools.sort(key=lambda x: x.weight, # weight 기준 내림차순
                 reverse=True)
print(power_tools)
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글