[Effective Python] | September 06, 2020
Effective Python: Second Edition 내용 정리
.sort()
method는 list 안에 들어있는 elements를 순서대로 재배열한다.sort
method는 오름차순(ascending order)을 기본으로 한다.sort method는 (특별한 method로 natural ordering를 정의하지 않은 이상) class와 같은 object에는 사용할 수 없다.
sort는 비교 method를 찾으려고 하는데 비교 method가 class에 정의되어 있지 않다면 비교해서 재배열 할 수 없다.
class Fruit:
def __init__(self, name, num):
self.name = name
self.num = num
def __repr__(self):
return f'Fruit({self.name}, {self.num})'
fruits = [
Fruit('apple', 10),
Fruit('banana', 5),
Fruit('cherry', 20),
Fruit('blueberry', 3)
]
fruits.sort()
>>> TypeError: '<' not supported between instances of 'Fruit' and 'Fruit'
sort
가 parameter를 가지지 않아도 동작할 수 있도록 특별한 method를 정의할 수 있다. (Item 73: Know How to Use heapq for Priority Queues 참조)sort
method는 parameter로 key
를 입력할 수 있는데, key는 어떤 것을 기준으로 sorting 할 것인지를 정해줄 수 있다.lambda
keyword를 활용해서 클래스의 속성을 알파벳 순으로 정렬할 수 있다.
class Fruit:
def __init__(self, name, num):
self.name = name
self.num = num
def __repr__(self):
return f'Fruit({self.name}, {self.num})'
fruits = [
Fruit('apple', 10),
Fruit('banana', 5),
Fruit('cherry', 20),
Fruit('blueberry', 3)
]
# 이름을 기준으로 알파벳순으로 정렬
fruits.sort(key=lambda x: x.name)
fruits
>>> [Fruit(apple, 10), Fruit(banana, 5), Fruit(blueberry, 3), Fruit(cherry, 20)]
tuple은 ordering 할 때 첫번째 element끼리 비교한 후 같으면 두번째 element끼리 비교.. 같으면 그 다음 element.. 를 비교하는 방식으로, 대소비교가 가능한 element가 나오면 거기서 ordering이 된다.
a = ('c', 1)
b = ('a', 1)
c = ('a', 2)
order = [a, b, c]
order
>>> [('c', 1), ('a', 1), ('a', 2)]
order.sort()
order
>>> [('a', 1), ('a', 2), ('c', 1)]
이러한 tuple의 ordering 방식을 활용해서, key 값에 tuple을 넣으면 여러 개의 속성을 기준으로 sort 할 수 있다.
fruits.sort(key=lambda x: (x.name, x.num))
다만, tuple을 사용하면 오름차순이든 내림차순이든 다 같은 방향으로 정렬된다.
fruits.sort(key=lambda x: (x.name, x.num), reverse=True)
숫자 형태의 값인 경우에는 -
를 붙여서 sorting 되는 방향을 바꿀 수 있다.
fruits.sort(key=lambda x: (x.name, -x.num))
같은 list에 sort() method를 여러번 호출해서 각각 다른 기준으로 sorting이 가능하다.
다만, 이렇게 여러번 입력할 때는, 가장 우선순위로 sorting 하고 싶은 value를 가장 마지막에 호출해야 한다.
이런 방법보다는 한줄로 사용하거나, -
를 붙여서 sort order 방향을 다르게 하는 게 더 읽기 좋고 코드도 적다.
따라서 이 방법은 꼭 필요할 때만 사용할 것을 권장한다.
# 이 경우 name 속성이 가장 우선순위로 정렬된다.
fruits.sort(key=lambda x: x.num, reverse=True)
fruits.sort(key=lambda x: x.name)