사전을 값별로 정렬하려면 어떻게합니까?


3422

데이터베이스의 두 필드 인 문자열 필드와 숫자 필드에서 읽은 값 사전이 있습니다. 문자열 필드는 고유하므로 사전의 키입니다.

키를 기준으로 정렬 할 수 있지만 값을 기준으로 정렬하려면 어떻게해야합니까?

참고 : 스택 오버플로 질문을 읽었습니다 . 사전 값으로 사전 목록을 정렬하려면 어떻게합니까? 사전 목록을 갖도록 코드를 변경할 수는 있지만 실제로 사전 목록이 필요하지 않으므로 오름차순 또는 내림차순으로 정렬하는 더 간단한 솔루션이 있는지 알고 싶었습니다.


9
사전 데이터 구조에는 고유 한 순서가 없습니다. 반복 할 수는 있지만 반복이 특정 순서를 따를 것이라는 보장은 없습니다. 이것은 의도적으로 설계된 것이므로 표현에 아노 터 데이터 구조를 사용하는 것이 가장 좋습니다.
Daishiman

135
"sorted ()"는 사전에서 작동 할 수 있고 정렬 된 키 목록을 반환하므로이를 알고 있다고 생각합니다. 그의 프로그램을 알지 못하면 누군가에게 잘못된 데이터 구조를 사용하고 있다고 말하는 것은 터무니 없습니다. 빠른 조회가 시간의 90 %를 필요로하는 것이라면, 아마 당신이 원하는 것일 수 있습니다.
bobpaul

사전 정렬에 대한 모든 3 개 개의 출력 (키, 값 모두가) 명확하고 간결한 스타일로 여기에 포함됩니다 stackoverflow.com/questions/16772071/sort-dict-by-value-python
JStrahl

2
@Daishiman 기본 클래스는 주문할 수 없지만 OrderedDict 는 물론입니다.
Taylor Edmiston

1
Python 3.6 이상에서 사전은 삽입 순서를 유지합니다. 물론 이것은 값을 기준으로 정렬 할 수있는 가능성과 동일하지 않지만 "사전 데이터 구조에 고유 한 순서가 없다"고 말하는 것은 더 이상 유효하지 않습니다.
Konrad Kocik

답변:


4946

파이썬 3.6 이상

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
{k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

오래된 파이썬

사전을 정렬 할 수 없으며 정렬 된 사전을 표시하기 만합니다. 사전은 본질적으로 순서가 없지만 목록 및 튜플과 같은 다른 유형은 그렇지 않습니다. 따라서 정렬 된 값을 나타내는 순서화 된 데이터 유형이 필요합니다. 목록은 아마도 튜플 목록 일 것입니다.

예를 들어

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x각 튜플의 두 번째 요소별로 정렬 된 튜플 목록이됩니다. dict(sorted_x) == x.

그리고 값 대신 키를 정렬하려는 사람들을 위해 :

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

압축 풀기가 허용되지 않으므로 Python3에서 [1] 사용할 수 있습니다

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])

출력을 받아쓰기로하려면 다음을 사용할 수 있습니다 collections.OrderedDict.

import collections

sorted_dict = collections.OrderedDict(sorted_x)

43
값 체계에 따른 다양한 사전 정렬 타이밍 : writeonly.wordpress.com/2008/08/30/…
Gregg Lind

164
sorted_x.reverse()당신에게 하강 (두 번째 튜플 요소에 의해) 주문 줄 것이다
apale saidimu

414
saidimu : 우리가 이미 사용하고 있기 때문에 인수 sorted()를 전달하는 것이 훨씬 효율적 reverse=True입니다.
rmh

121
python3에서는 람다를 사용했습니다 sorted(d.items(), key=lambda x: x[1]). 이것은 파이썬 2.x에서 작동합니까?
Keyo

84
2.7에서 OrderedDict가 컬렉션에 추가되었습니다. 정렬 예 : docs.python.org/library/…
monkut

1262

다음과 같이 간단합니다. sorted(dict1, key=dict1.get)

실제로 "사전 값으로 정렬"을 수행 할 수 있습니다. 최근 코드 골프 (스택 오버플로 질문 코드 골프 : 단어 빈도 차트 ) 에서 그렇게해야했습니다 . 요약하면, 문제는 일종의 문제입니다. 텍스트가 주어지면 각 단어가 얼마나 자주 나오는지 세고 가장 많이 나오는 단어 목록을 빈도를 기준으로 정렬하여 표시합니다.

단어를 키로 사용하고 각 단어의 발생 횟수를 값으로 사용하여 사전을 구성하는 경우 다음과 같이 단순화하십시오.

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
    d[w] += 1

그런 다음 사용 빈도별로 정렬 된 단어 목록을 얻을 수 있습니다 sorted(d, key=d.get). 정렬은 단어 발생 횟수를 정렬 키로 사용하여 사전 키를 반복합니다.

for w in sorted(d, key=d.get, reverse=True):
    print(w, d[w])

나는 사람들이 종종 "키로 사전을 쉽게 정렬 할 수 있지만 어떻게 값으로 정렬 하는가"라는 의미를 설명하기 위해이 상세한 설명을 작성하고있다. 그리고 해결책은 위에 표시된 것처럼 값을 기반으로 일종의 키 목록을 수행하는 것입니다.


31
이것은 또한 좋지만 key=operator.itemgetter(1)효율성보다 확장 성이 key=d.get
뛰어나야합니다.

3
@raylu itemgetter를 사용하여 "작동하지 않습니다"동작을 관찰합니다. ----- ------ from operator import itemgetter d = {"a":7, "b":1, "c":5, "d":3} sorted_keys = sorted(d, key=itemgetter, reverse=True) for key in sorted_keys: print "%s: %d" % (key, d[key]) > b : 1 c : 5 a : 7 d : 3 코드를 실행할 때마다 결과가 변경됩니다. . (죄송합니다, 코드가 제대로 표시되지 않습니다)
bli

12
@bli sorted_keys = sorted(d.items(), key=itemgetter(1), reverse=True)and for key, val in sorted_keys: print "%s: %d" % (key, val)-itemgetter는 함수가 호출 될 때 함수를 생성하므로 예제처럼 직접 사용하지 않습니다. 그리고 dict에 대한 평범한 반복은 값이없는 키를 사용합니다
Izkata

18
나는 당신에게 관심을 가질만한 방법을 collections.Counter가지고있는 당신에게 말할 미래에서왔다 most_common:)
Eevee

2
@Eevee-f2f가 아닌 짧은 의견에서 오해의 위험이 있습니다. Amuzing tidbit : collections.Counter2.7에 추가되었으며 거의 ​​7 년 전에 출시되었습니다! (나는 그때 그것에 대해 몰랐다-게다가 나는 게임의 유일한 강박 관념 인 간결성을 위해 코드 골프에서 그것을 피했을 것이다)
Nas Banov

857

당신은 사용할 수 있습니다 :

sorted(d.items(), key=lambda x: x[1])

사전에서 각 항목의 값을 최소에서 최대로 정렬하여 사전을 정렬합니다.

내림차순으로 정렬하려면 다음을 추가하십시오 reverse=True.

sorted(d.items(), key=lambda x: x[1], reverse=True)

입력:

d = {'one':1,'three':3,'five':5,'two':2,'four':4}
a = sorted(d.items(), key=lambda x: x[1])    
print(a)

산출:

[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]

내가 본 것 ( docs.python.org/2/library/… )에는 OrderedDict라는 클래스가 있습니다. 코드 예제에서 람다를 사용하여 정렬 할 수는 있지만 개인적으로 시도하지는 않았습니다 .P
UsAndRufus

53
key=lambda (k, v): v개인적으로 선호합니다
Claudiu

35
@Claudiu 나는 그 (k, v)구문도 좋아 하지만 튜플 매개 변수 풀기 가 제거 된 Python 3에서는 사용할 수 없습니다 .
Bob Stein

2
dict(sorted(d.items(), key=lambda x: x[1])).
Dr_Hope

3
분류 된 튜플 목록에서 dict을 작성하면 순서가 다시
사라집니다

233

딕 트는 정렬 할 수 없지만 정렬 된 목록을 만들 수 있습니다.

정렬 된 dict 값 목록 :

sorted(d.values())

값별로 정렬 된 (키, 값) 쌍 목록 :

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))

같은 값을 가진 키는 어떤 순서로 배치됩니까? 먼저 키를 기준으로 목록을 정렬 한 다음 값을 기준으로 정렬했지만 동일한 값을 가진 키의 순서는 유지되지 않습니다.
SabreWolfy 2016 년

1
CPython 3.6부터 시작하여 3.7을 시작으로 다른 모든 Python 구현
Boris

161

최근 Python 2.7에는 새로운 OrderedDict 유형이 있으며, 항목이 추가 된 순서를 기억합니다.

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1

>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

값을 기준으로 원본에서 새로운 순서 사전을 만들려면 :

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

OrderedDict는 일반적인 dict처럼 행동합니다 :

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4

>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])

5
이것은 질문에 관한 것이 아닙니다-그것은 키의 순서를 유지하는 것이 아니라 "가치에 의한 분류"에 관한 것입니다
Nas Banov

10
@ Nas Banov : 키로 정렬하지 않습니다. 순서대로 정렬하고 항목을 만듭니다. 이 경우 값을 기준으로 정렬합니다. 불행히도 3 항목 dict은 불행히도 선택되어 순서와 값이 같고 키로 정렬 할 때 순서가 동일하므로 샘플 dict을 확장했습니다.
mykhal

sorted(d.items(), key=lambda x: x[1])람다에 x걸리는 이유 를 설명 할 수 있습니까 x[1]? 왜 그렇게 할 수 x[0]없습니까? 대단히 감사합니다!
JZAU

1
@Boern d.items()은리스트와 같은 (key, value)튜플 컨테이너를 반환합니다 . [0]튜플의 첫 번째 요소 인 키에 [1]액세스하고 두 번째 요소 인 값에 액세스합니다.
BallpointBen

2
참고 : (A CPython의 / PyPy 구현 세부 사항)를 3.6로하고 (파이썬 언어 보증 등)에 3.7으로는, 보통은 dict그냥 교체 할 수 있도록 삽입뿐만 아니라 명령이다 OrderedDictdict코드를 현대 파이썬에서 실행. OrderedDict기존 dict( move_to_end/ 포함 popitem) 의 순서를 재정렬 하거나 순서에 민감하기 위해 평등 비교가 필요하지 않으면 더 이상 실제로 필요하지 않습니다 . 평범한 것보다 훨씬 많은 메모리를 사용 dict하므로 가능하다면 갈 수 dict있는 방법입니다.
ShadowRanger

104

업데이트 : Python 3.5를 사용하는 2015 년 12 월 5 일

허용 된 답변이 유용하다는 것을 알았지 만 표준 라이브러리 컬렉션 모듈 의 OrderedDict 를 실행 가능한 현대 대안 으로 참조하도록 업데이트되지 않았다는 사실에 놀랐습니다 .이 유형의 문제를 정확하게 해결하도록 설계되었습니다.

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

공식 OrderedDict 문서도 매우 유사한 예제를 제공하지만 정렬 함수에 람다를 사용합니다.

# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

86

행크 게이의 답변 과 거의 같습니다.

sorted([(value,key) for (key,value) in mydict.items()])

또는 John Fouhy가 제안한대로 약간 최적화되었습니다.

sorted((value,key) for (key,value) in mydict.items())

9
Hank Gay의 답변과 마찬가지로 대괄호가 필요하지 않습니다. sorted ()는 생성기 표현식과 같은 반복 가능한 것을 취합니다.
John Fouhy

(key, value)로 끝나기 위해 (value, key) 튜플 요소를 교체해야 할 수도 있습니다. 그런 다음 또 다른 목록 이해가 필요합니다. [(key, value) for (value, key) in sorted_list_of_tuples]
saidimu apale

아니요, sorted목록을 다시 작성해야하고 gencomp에서 다시 작성하는 것이 더 빠르기 때문에 대괄호를 두는 것이 좋습니다 . 코드 골프에 좋고 속도에 좋지 않습니다. 못생긴 ([])버전을 유지하십시오 .
Jean-François Fabre

75

namedtuple 을 사용하는 것이 종종 편리 할 수 ​​있습니다 . 예를 들어, 키로 'name'사전을 값으로 사용하고 'score'를 값으로 정렬하고 'score'로 정렬하려고합니다.

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

가장 낮은 점수로 먼저 정렬 :

worst = sorted(Player(v,k) for (k,v) in d.items())

가장 높은 점수로 먼저 정렬 :

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

이제 다음과 같은 이름과 점수를 얻을 수 있습니다.

player = best[1]
player.name
    'Richard'
player.score
    7

사전으로 다시 변환하려면 어떻게해야합니까?
rowana 2019

as_list = [d.items ()에서 (k, v)에 대한 선수 (v, k)] as_dict = dict ((as_list에서 p에 대한 (p.name, p.score))
Remi

72

현재 파이썬 3.6 내장 딕셔너리 명령을 받게됩니다

희소식이므로, 고유 한 문자열 ID를 키로, 숫자 값을 내장 된 Python v3.6 + dict로 데이터베이스에서 검색 한 OP의 원래 매핑 쌍 사용 사례는 이제 삽입 순서를 존중해야합니다.

데이터베이스 쿼리에서 결과로 나온 두 개의 열 테이블 표현식이 다음과 같은 경우 :

SELECT a_key, a_value FROM a_table ORDER BY a_value;

k_seq 및 v_seq (숫자 색인으로 정렬되고 물론 동일한 길이로 정렬 됨)라는 두 개의 Python 튜플에 저장됩니다.

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

나중에 다음과 같이 출력하도록 허용하십시오.

for k, v in ordered_map.items():
    print(k, v)

이 경우 새로운 파이썬 3.6+ 내장 dict!

foo 0
bar 1
baz 42

v의 값당 동일한 순서로

Python 3.5에서 내 컴퓨터의 설치 위치는 현재 다음과 같습니다.

bar 1
foo 0
baz 42

세부:

Raymond Hettinger가 2012 년에 제안한대로 ( " Python-dev의 메일은 "더 빠른 반복이 포함 된 더 컴팩트 한 사전 "참조 ), 이제 (2016 년) Victor Stinner의 메일에서 "Python 3.6 dict의 제목은 python 3.6 dict이됩니다. Python 3.6에서 문제 27350 "Compact and ordered dict" 의 수정 / 구현으로 인해 키워드가 정렬되었습니다. " 이제 삽입 순서를 유지하기 위해 내장 dict를 사용할 수 있습니다 !!

바라건대 이것은 첫 번째 단계로 얇은 계층 OrderedDict 구현으로 이어질 것입니다. @ JimFasarakis-Hilliard가 지적했듯이 일부는 앞으로도 OrderedDict 유형의 사용 사례를 참조하십시오. 필자는 파이썬 커뮤니티가 시간의 시험을 견딜 수 있는지, 다음 단계는 무엇인지 신중하게 검사 할 것이라고 생각합니다.

다음과 같은 안정적인 순서로 열린 가능성을 놓치지 않도록 코딩 습관을 재고 할 시간입니다.

  • 키워드 인수 및
  • (중급) dict 스토리지

첫 번째는 함수 및 메소드 구현시 디스패치를 ​​용이하게하기 때문입니다.

두 번째는 dict파이프 라인 처리에서 s를 중간 저장소로 보다 쉽게 ​​사용하도록 권장합니다 .

Raymond Hettinger 는 자신의 샌프란시스코 Python Meetup 그룹 프레젠테이션 2016-DEC-08에서 " The Python Behind Python 3.6 사전 "을 설명하는 문서를 친절하게 제공 했습니다.

그리고 아마도 꽤 많은 Stack Overflow 장식 질문 및 답변 페이지가이 정보의 변형을 수신 할 것이며 많은 고품질 답변은 버전 별 업데이트도 필요합니다.

Caveat Emptor (아래 업데이트 2017-12-15 참조) :

@ajcr은 올바로 언급했듯이 "이 새로운 구현의 순서 유지 측면은 구현 세부 사항으로 간주되며 의존해서는 안됩니다." ( Whatsnew36에서 ) nit picking이 아니라 인용이 약간 비관적이었습니다. "(이것은 미래에 변경 될 수 있지만, 현재 및 미래의 모든 파이썬 구현에 대한 순서 보존 의미론을 요구하도록 언어 스펙을 변경하기 전에 몇 가지 릴리스에 대해 언어로이 새로운 dict 구현을 갖는 것이 바람직합니다. "임의의 반복 순서가 여전히 유효한 이전 버전의 언어 (예 : Python 3.5)와의 하위 호환성을 유지하는 데 도움이됩니다."

따라서 일부 인간 언어 (예 : 독일어)에서와 같이, 사용법은 언어를 형성하며, 의지는 이제 whatsnew36 에서 선언되었습니다 .

2017-12-15 업데이트 :

Guido van Rossum 은 python-dev list 로 보낸 메일에서 다음과 같이 선언했습니다.

그렇게 만들어. "사전 삽입 순서 유지"는 판결입니다. 감사!

따라서 dict 삽입 순서의 버전 3.6 CPython 부작용은 이제 언어 사양의 일부가되었습니다 (더 이상 구현 세부 사항이 아님). 이 메일 쓰레드는 또한 collections.OrderedDict토론 중에 Raymond Hettinger가 상기 한 것처럼 독특한 디자인 목표를 보여 주었습니다.


15
링크 된 'whatsnew'페이지의 경고를 강조해야합니다. 이 새로운 구현의 순서 유지 측면은 구현 세부 사항으로 간주되며 이에 의존해서는 안됩니다 . 아무도 dict타입이 코드에서 삽입 순서를 존중 한다고 가정해서는 안됩니다 . 이것은 언어 정의의 일부가 아니며 향후 릴리스에서 구현이 변경 될 수 있습니다. OrderedDict주문을 보장하기 위해 계속 사용하십시오 .
Alex Riley

@ajcr 감사의 말을 전합니다. 스마일리와 아마도 내 응답에 짜여진 것처럼, 변경 사항은 방대하지만 물론 CPython (참조 구현) 및 PyPy에서만 사용할 수 있습니다. 완전히 다른 무언가를 위해 ... 나는 사람-기계 명령을 코딩 할 때 구현되지 않은 세부 사항과 거의 이야기하지 않습니다. 그것이 자이 썬일 뿐이라면 ;-) ... 나는 그것을 쓸 용기가 없었을 것이다.
Dilettant

OrderedDict확실히 떨어지지 않을 것입니다. 대신, 그것은 현재 dict 구현을 둘러싼 얇은 래퍼가 될 것입니다 (따라서 더 컴팩트해질 것이라고 덧붙일 수 있습니다). 이 스 니펫을 추가하는 ImportError것은 사용하지 않는 독자를 오도하기 때문에 가장 좋은 아이디어 OrderedDict는 아닙니다.
Dimitris Fasarakis Hilliard

@ JimFasarakis-Hilliard 의견에 감사드립니다. "최고의 최고의 아이디어"는 나를 미소 짓게했다-미래는 종종 예측하기 어렵다. 그러나 귀하의 제안이 출처를 확인하고 시도한 다음 그에 따라 답변을 업데이트하는 것이 좋습니다. 다시 감사합니다.
Dilettant

8
@AlexRiley이 경고는 더 이상 정확하지 않습니다. Python3.7은 정렬 된 사전을 보장합니다.
gerrit

42

나는 같은 문제가 있었고 다음과 같이 해결했다.

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

( "dict을 정렬 할 수 없습니다"라고 대답 한 사람들은 질문을 읽지 못했습니다! 사실, "키를 정렬 할 수 있지만 값을 기준으로 정렬 할 수있는 방법은 무엇입니까?" 키는 해당 값의 값에 따라 정렬됩니다.)

순서가 잘 정의되지 않았습니다 (동일한 값을 가진 키는 출력 목록에서 임의 순서로 표시됨).


1
결과에서 값이 누락되었습니다
Dejell

사전을 반복하고 키로 값을 가져 오는 것이므로 성능면에서는 최적의 솔루션이 아닙니다.
Ron Klein

1
@Dejell : 기고자에 따르면, 그는 질문을 "값에 따라 정렬 된 키 목록을 얻을 수 있습니까?"라고 해석합니다. 결과에 값이 필요하지 않으며 사전에 값이 있습니다.
Max

36

값이 숫자 인 경우 컬렉션Counter 에서 사용할 수도 있습니다 .

from collections import Counter

x = {'hello': 1, 'python': 5, 'world': 3}
c = Counter(x)
print(c.most_common())

>> [('python', 5), ('world', 3), ('hello', 1)]    

사전이 >>> x = { 'hello': 1, 'python': 5, 'world': 300} 인 경우
James Sapam

@yopy가 Counter({'hello':1, 'python':5, 'world':300}).most_common()제공합니다 [('world', 300), ('python', 5), ('hello', 1)]. 이것은 실제로 모든 정렬 가능한 값 유형에서 작동합니다 ( 다른 많은 카운터 작업에서는 값을 정수와 비교할 필요가 있지만).
lvc

34

Python 2.7에서는 간단히 다음을 수행하십시오.

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

복사하여 붙여 넣기 : http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

즐겨 ;-)


25

이것은 코드입니다.

import operator
origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
    print foo

print "\n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
    print foo

print "\n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
    print foo

결과는 다음과 같습니다.

기발한

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

로플

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

계급

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}

25

다음 방법을 시도하십시오. 다음 데이터를 사용하여 mydict라는 사전을 정의하겠습니다.

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

사전을 키로 정렬하려면 다음과 같이 할 수 있습니다.

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

다음 출력을 반환해야합니다.

alan: 2
bob: 1
carl: 40
danny: 3

반면에 (질문에서 요청한대로) 값을 기준으로 사전을 정렬하려면 다음을 수행 할 수 있습니다.

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

이 명령의 결과 (사전을 값으로 정렬)는 다음을 반환해야합니다.

bob: 1
alan: 2
danny: 3
carl: 40

대박! for key, value in sorted(mydict.iteritems(), key=lambda (k,v): v["score"]):하위
키로

Python3의 람다 근처에서 구문 오류가 발생합니다.
Suleman Elahi

21

Python 3.6부터 dict객체는 삽입 순서에 따라 정렬됩니다. 공식적으로 Python 3.7의 사양에 있습니다.

>>> words = {"python": 2, "blah": 4, "alice": 3}
>>> dict(sorted(words.items(), key=lambda x: x[1]))
{'python': 2, 'alice': 3, 'blah': 4}

그 전에는를 사용해야했습니다 OrderedDict.

파이썬 3.7 문서 는 말합니다 :

버전 3.7으로 변경 : 사전 순서는 삽입 순서로 보장됩니다. 이 동작은 3.6의 CPython의 구현 세부 사항입니다.


잘 작동합니다! dict(sorted(words.items(), key=lambda x: x[1], reverse=True))for DESC
vizyourdata

20

"거꾸로 된 색인"을 만들 수도 있습니다.

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

이제 당신의 역은 가치가 있습니다; 각 값에는 적용 가능한 키 목록이 있습니다.

for k in sorted(inverse):
    print k, inverse[k]

19

collections.Counter 를 사용할 수 있습니다 . 숫자 및 숫자가 아닌 값 모두에 적용됩니다.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

7
Ivan Sas의 답변 과 다른 점은 무엇입니까?
Peter Mortensen

15

값으로 영구적으로 정렬 된 사전 인 건너 뛰기 dict 을 사용할 수 있습니다 .

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

당신이 사용하는 경우 keys(), values()또는 items()당신은 값으로 정렬 된 순서로 반복됩니다.

스킵리스트 데이터 구조를 사용하여 구현됩니다 .


정렬 순서를 바꿀 수 있습니까? 지금 당장은 오름차순이지만 내림차순입니다.
Suleman Elahi

afaik 당신은 순서를
바꾸

와우, 나는 그렇게 생각하지 않습니다 ... 감사합니다.
Suleman Elahi

14

키에 전달할 수있는 사용자 정의 기능을 사용할 수도 있습니다.

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

12
from django.utils.datastructures import SortedDict

def sortedDictByKey(self,data):
    """Sorted dictionary order by key"""
    sortedDict = SortedDict()
    if data:
        if isinstance(data, dict):
            sortedKey = sorted(data.keys())
            for k in sortedKey:
                sortedDict[k] = data[k]
    return sortedDict

2
질문은 키가 아닌 값으로 정렬하는 것입니다 ... 나는 기능을 보는 것을 좋아합니다. 컬렉션을 가져올 수 있으며 물론 sorted (data.values ​​())
Remi

10

Dilettant가 지적한 것처럼 Python 3.6은 이제 순서를 유지합니다 ! 나는 iterable (tuple, list, dict)의 정렬을 용이하게하는 내가 작성한 함수를 공유한다고 생각했다. 후자의 경우 키 또는 값을 기준으로 정렬 할 수 있으며 숫자 비교를 고려할 수 있습니다. 3.6 이상인 경우에만!

int뿐만 아니라 문자열을 포함하는 iterable에서 sorted를 사용하려고하면 sorted ()가 실패합니다. 물론 str ()을 사용하여 문자열을 강제로 비교할 수 있습니다. 그러나 어떤 경우에는 당신이하고 싶은 실제 숫자 비교 12보다 작은 20(문자열 비교의 경우하지 않은 참조). 그래서 나는 다음을 생각해 냈습니다. 명시적인 숫자 비교를 원할 경우 num_as_num모든 값을 부동 소수점으로 변환하여 명시적인 숫자 정렬을 시도 하는 플래그 를 사용할 수 있습니다 . 성공하면 숫자 정렬을 수행하고 그렇지 않으면 문자열 비교를 사용합니다.

개선 또는 푸시 요청에 대한 의견은 환영합니다.

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")

9

다음은 zip on d.values()및을d.keys() 사용하는 솔루션 입니다. 이 링크 아래의 몇 줄은 (사전보기 객체에서) 다음과 같습니다.

이렇게하면 zip ()을 사용하여 (값, 키) 쌍을 만들 수 있습니다. pairs = zip (d.values ​​(), d.keys ()).

따라서 다음을 수행 할 수 있습니다.

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]

9

물론, OrderedDict정기적 인 파이썬 사전은 원래 순서를 유지하지 않기 때문에 사용해야 합니다.

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key=lambda x: x[1]))

Python 2.7 이상이 없으면 생성기 함수의 값을 반복하는 것이 가장 좋습니다. (AN가 OrderedDict2.4 및 2.6 여기 지만,

a) 나는 그것이 얼마나 잘 작동하는지 모른다

b) 물론 다운로드하여 설치해야합니다. 관리자 액세스 권한이 없으면 옵션이 종료 될까봐 걱정됩니다.)


def gen(originalDict):
    for x, y in sorted(zip(originalDict.keys(), originalDict.values()), key=lambda z: z[1]):
        yield (x, y)
    #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 

for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

모든 값을 인쇄 할 수도 있습니다

for bleh, meh in gen(myDict):
    print(bleh, meh)

Python 3.0 이상을 사용하지 않는 경우 인쇄 후 괄호를 제거하십시오


일반 파이썬 사전은 원래 순서를 유지하지 않습니다 . Python 3.7부터는 그렇게합니다.
gerrit

7

dicts 에서 ValueSortedDict 사용 :

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

6

이것은 3.1.x에서 작동합니다.

import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)

6

Python for Everybody 에서 관련 기술을 배웠습니다 .

사전을 정렬하는 데 도움이되도록 임시 목록을 사용할 수 있습니다.

#Assume dictionary to be:
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}

# create a temporary list
tmp = []

# iterate through the dictionary and append each tuple into the temporary list 
for key, value in d.items():
    tmptuple = (value, key)
    tmp.append(tmptuple)

# sort the list in ascending order
tmp = sorted(tmp)

print (tmp)

목록을 내림차순으로 정렬하려면 원래 정렬 행을 다음과 같이 변경하십시오.

tmp = sorted(tmp, reverse=True)

리스트 이해를 사용하면 하나의 라이너는 다음과 같습니다.

#Assuming the dictionary looks like
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
#One liner for sorting in ascending order
print (sorted([(v, k) for k, v in d.items()]))
#One liner for sorting in descending order
print (sorted([(v, k) for k, v in d.items()], reverse=True))

샘플 출력 :

#Asending order
[(1.0, 'orange'), (500.1, 'apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
#Descending order
[(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'apple'), (1.0, 'orange')]

이것은 값이 아닌 키를 기준으로 정렬됩니다.
Rubel

초기 형식으로 인쇄하려면 print ([v, k의 경우 정렬 된 ([(v, k)의 경우 k, v의 경우 d.items ()]))])와 같이 인쇄해야합니다. 출력은 [( 'orange', 1.0), ( 'apple', 500.1), ( 'pineapple', 789.0), ( 'banana', 1500.2)]입니다. v, k에 대해 [(k, v)에 대해 정렬 된 경우 (d.items ()에서 k, v에 대한 [(v, k), reverse = True)]의 경우 출력은 다음과 같습니다. [( 'banana', 1500.2), ( 'pineapple', 789.0), ( 'apple', 500.1), ( 'orange', 1.0)]
헤르메스 모랄레스

5

dict을 반복하고 값을 내림차순으로 정렬합니다.

$ python --version
Python 3.2.2

$ cat sort_dict_by_val_desc.py 
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for word in sorted(dictionary, key=dictionary.get, reverse=True):
  print(word, dictionary[word])

$ python sort_dict_by_val_desc.py 
aina 5
tuli 4
joka 3
sana 2
siis 1

5

값이 정수이고 Python 2.7 이상을 사용 collections.Counter하는 경우 대신 대신 사용할 수 있습니다 dict. 이 most_common방법은 값으로 정렬 된 모든 항목을 제공합니다.


5

완벽을 기하기 위해 heapq 사용하여 솔루션을 게시하고 있습니다 . 이 방법은 숫자 값과 숫자가 아닌 값 모두에서 작동합니다.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> x_items = x.items()
>>> heapq.heapify(x_items)
>>> #To sort in reverse order
>>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

4

이전 버전의 Python 과의 호환성을 유지해야하는 요구 사항으로 인해 OrderedDict 솔루션이 현명하지 않다고 생각합니다. Python 2.7 및 이전 버전에서 작동하는 것을 원합니다.

그러나 다른 대답에서 언급 한 수집 솔루션은 절대적으로 훌륭합니다. 사전의 경우 매우 중요한 키와 가치 사이의 연결을 재교육하기 때문입니다.

다른 답변에 제시된 최고의 선택에 동의하지 않습니다. 왜냐하면 키를 버리기 때문입니다.

위에서 언급 한 솔루션 (아래에 표시된 코드)을 사용하고 키와 값 모두에 대한 액세스 권한을 유지했으며 내 경우에는 순서가 값에 있었지만 중요한 것은 값을 주문 한 후 키의 순서였습니다.

from collections import Counter

x = {'hello':1, 'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.