Python 3은 값을 기준으로 dict를 정렬합니다.


79

내가 찾은 유일한 방법은 python2에서 작동하거나 튜플 목록 만 반환합니다.

{"aa": 3, "bb": 4, "cc": 2, "dd": 1}값을 기준으로 사전을 정렬 할 수 있습니까?

내가 달성하고자하는 정렬 된 사전의 순서는 가장 큰 것에서 가장 작은 것까지입니다. 결과가 다음과 같기를 바랍니다.

bb 4
aa 3
cc 2
dd 1

정렬 후 텍스트 파일에 저장하고 싶습니다.

답변:


120

itemgetter(다른 답변 참조) 큰 사전에는 (내가 아는 바와 같이) 더 효율적이지만 일반적인 경우에는 그것이 이긴다고 생각합니다 d.get. 그리고 추가 import.

>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> for k in sorted(d, key=d.get, reverse=True):
...     k, d[k]
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)

선택적으로 설정할 수있는 참고 d.__getitem__key위에 작은 성능 향상을 제공 할 수 있습니다 기능 d.get.


1
2 행에서 구문을 설명 해주시겠습니까? 저는 파이썬 3을 배우는 중이며 이것을 이해하고 싶습니다.
Serge

2
물론입니다.하지만 당신이 이해하지 못하는 것을 알면 더 쉬울 것입니다. [x for x in iterable]Python List Comprehension (google)은 목록을 생성하는 데 매우 일반적이고 효율적인 Python입니다. (k, d[k])두 요소 튜플이고 두 번째 요소 ( d[k])는 사전의 값입니다. sorted()값별로 정렬 된 사전의 키를 반환하는 내장 함수입니다. key=d.get아는 것이 사소하지 않은 내 대답의 열쇠를 사용 합니다. 내장 함수를 아는 것은 필수적입니다. 도움이 되었기를 바랍니다.
SzieberthAdam

감사합니다! [x for x in iterable]"목록의 이해"를 소개 과정에서 누락 된 것입니다. 이제 그것에 대해 읽고 있습니다 (이름을 모르는 것을 찾기가 어려웠습니다).
Serge

29
from collections import OrderedDict
from operator import itemgetter    

d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))

인쇄물

OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])

마지막 문장에서 튜플 목록이 잘 작동하는 것처럼 보입니다.

from operator import itemgetter  

d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
    print(key, value)

어느 인쇄

bb 4
aa 3
cc 2
dd 1

당신의 도움을 주셔서 감사합니다. 나는 해결책 중 하나가 이와 비슷한 것이라고 생각했습니다.

1
dict지금 삽입 순서를 유지하므로 사용에 이유가 없다OrderedDict
보리스

2
나는 두 가지 이유를 생각할 수 있습니다. 첫째는 당신이 순서에 관심이 있음을 분명히하고, 둘째로 누군가가 오래된 인터프리터에서 당신의 코드를 실행할 수 있고 조용히 오작동하는 것은 좋은 결과가 아닙니다.
plugwash

17

딕셔너리 이해를 사용하여 역순 (최대에서 최소) 으로 을 정렬 할 수 있습니다 .

{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}

을 오름차순 (가장 작은 것에서 가장 큰 것)으로 정렬하려는 경우

{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}

당신은별로 정렬하려면 키를 오름차순으로

{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}

이것은 사전이 삽입 순서를 유지하기 때문에 CPython 3.6+ 및 Python 3.7+의 모든 구현에서 작동합니다.


12

또 다른 방법은 람다 식을 사용하는 것입니다. 인터프리터 버전과 정렬 된 사전 또는 정렬 된 키-값 튜플 (OP처럼)을 만들 것인지 여부에 따라 허용되는 답변보다 빠를 수도 있습니다.

d = {'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1}
s = sorted(d.items(), key=lambda x: x[1], reverse=True)

for k, v in s:
    print(k, v)

1
귀하의 코드가 작동하는 동안 사전이 추가 된 것과 동일한 순서로 항목을 반환한다고 보장하지 않습니다.
Ivan

2
@Ivan 감사합니다 – CPython 3.6 이상에서는 dict가 순서를 유지하고 있지만 가까운 시일 내에 언어 기능이 될 가능성이 있지만 여기서 dict ()의 불필요한 사용을 제거했습니다 ( docs.python.org/3 /whatsnew/3.6.html )
Bede Constantinides

고마워요. 재미 있네요. 또한-마지막 print(s)에는 루프 대신에 할 수 있습니다. :)
Ivan

1
dict3.7로 시작하는 모든 비단뱀의 순서를 유지 s의
보리스

1
실제로 10 % 미만입니다. 100,000 요소 사전이있는 Python 3.8.6에서 54ms 대 57.3ms를 얻지 만 기술적으로는 여전히 느립니다. 그것들을 제거해야한다고 생각합니다. 이는 가치있는 최적화가 아닙니다.
Boris

10

사전을 정렬하려면 연산자 모듈을 사용할 수 있습니다. 다음 은 운영자 모듈 문서입니다.

import operator                             #Importing operator module
dc =  {"aa": 3, "bb": 4, "cc": 2, "dd": 1}  #Dictionary to be sorted

dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort

출력 순서는 정렬 된 목록이됩니다.

[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]

키와 관련하여 정렬하려면 다음을 사용할 수 있습니다.

dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)

출력 순서는 다음과 같습니다.

[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]

폴 드레이퍼의 대답은 이미 단지 전체 라이브러리를 가져하지 ... 연산자를 사용
살바토레 Cosentino

0

사전을 정렬하고 나중에 사전으로 작동하도록 유지 하려면 표준 라이브러리에서 OrderedDict 를 사용할 수 있습니다 .

이것이 필요한 것이 아니라면 튜플 목록을 남기는 정렬 함수를 재고하는 것이 좋습니다. 순서가 지정된 키-값 쌍 (튜플) 목록이 아니라면 어떤 출력을 원했습니까?


dict지금 삽입 순서를 유지하므로 사용에 이유가 없다OrderedDict
보리스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.