on1ystar 머릿속을 정리, 기록하는 곳

Python 딕셔너리 정렬하기 - sorted(), operator 모듈



딕셔너리를 정렬하는 방법 중에 파이썬의 내장 함수은 sorted()operator 라이브러리의 itemgetter()를 이용하는 방법이다.


sorted(iterable, *, key=None, reverse=False)


iterable로 부터 새로운 정렬된 리스트를 만드는 sorted() 내장 함수

https://docs.python.org/ko/3/howto/sorting.html

list내장 함수은 list.sort()는 기존의 리스트를 정렬함으로써 값이 변경되는데, sorted()는 정렬된 새로운 리스트를 반환한다.

기본적으로 오름차순 정렬이며, reverse=True로 키워드 인자를 주면 내림차순 정렬도 가능하다.

또한, 딕셔너리를 정렬하기 위해서는 key 키워드 인자를 활용해야 한다. 값으로는 각 리스트 요소에 대해 호출할 함수를 지정할 수 있다.

>>> student_tuples = [
	    ('john', 'A', 15),
	    ('jane', 'B', 12),
	    ('dave', 'B', 10),
		]
>>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

lambda를 사용하는 것보다 더 빠르고 쉬운 방법은 operator 모듈을 사용하는 것이다.


operator


파이썬의 내장 연산자에 해당하는 효율적인 함수 집합을 내보냅니다. 또한, operator 모듈은 일반화된 어트리뷰트와 항목 조회를 위한 도구도 정의합니다. 이것은 map(), sorted(), itertools.groupby() 또는 함수 인자를 기대하는 다른 함수의 인자로 사용될 고속 필드 추출기를 만드는 데 유용합니다.

https://docs.python.org/ko/3/library/operator.html#module-operator

operator모듈의 itemgetter()attrgetter()는 item을 꺼내는 callable object를 반환한다.

callable object는 python에서 객체(class)내에 call()이 정의되어 호출 가능한 객체다.

>>> soldier = dict(rank='captain', name='dotterbart')
...t = operator.itemgetter('rank')
>>> t
operator.itemgetter('rank')
>>> t(soldier)
'captain'

operator.itemgetter('rank')를 변수 t에 저장함으로써, t는 호출 가능한 객체가 된다. 따라서 soldiert의 인자로 주면, tsoldier로부터 rank라는 key 값을 찾아 반환한다.

따라서 sorted()key 매개 변수 값으로 활용할 수 있다.

>>> from operator import itemgetter, attrgetter
# 위에 정의한 student_tuples ...
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]


딕셔너리 정렬


이제 위에서 살펴봤던 sorted()operator 모듈을 이용해 딕셔너리를 정렬할 수 있다.

>>> from operator import itemgetter
>>> test_dic = { 'a': 3, 'c': 2, 'b': 1}
>>> sorted(test_dic.items(), key=itemgetter(0))
[('a', 3), ('b', 1), ('c', 2)]
>>> sorted(test_dic.items(), key=itemgetter(1))
[('b', 1), ('c', 2), ('a', 3)]
>>> sorted(test_dic.items(), key=itemgetter(1), reverse=True)
[('a', 3), ('c', 2), ('b', 1)]

itemgetter(0)은 key를 가리킬 테고, itemgetter(1)은 value를 가리키기 때문에 위와 같은 결과를 확인할 수 있다.

주의해야 할 점은 딕셔너리 객체 자체를 넘겨주는 것이 아닌, items() 메소드를 호출해 넘겨줘야 한다. 위에서 test_dic만을 넘겨주면 자체적으로 key값만을 정렬한 리스트를 반환해 주기 때문이다.(for문과 마찬가지)

>>> sorted(test_dic)
['a', 'b', 'c']