2009-03-23 12 views
14

Mam słownika takiego:Jak mogę iterować po słowniku Pythona uporządkowanym według wartości?

{ 'a': 6, 'b': 1, 'c': 2 } 

chciałbym iteracyjne nad nim wartością, a nie klucza. Innymi słowy:

(b, 1) 
(c, 2) 
(a, 6) 

Jaki jest najprostszy sposób?

+0

powielać http://stackoverflow.com/questions/613183/sort-a-dictionary-in-python-by-the-value –

+2

Nie dupe. Drugi chce posortować słownik, co jest niemożliwe. Chcę iterować po słowniku w posortowanej kolejności. – mike

+0

i kod jest dokładnie taki sam. – SilentGhost

Odpowiedz

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

dla tych z was, którzy nienawidzą lambda :-)

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

jednak operator wersji wymaga CPython 2.5+

+0

Potrzebuję kluczy i przedmiotów, a nie tylko przedmiotów. – mike

+0

dictionary.items() udostępnia zarówno klucze, jak i wartości, a nie tylko klucze. –

+1

@Mike: elementy są parami (klucz, wartość). – vartec

3

Sposób items daje listę (klucz, wartość) krotek, które można sortować za pomocą sorted i niestandardowego klucza sortowania:

Python 2.5.1 (r251:54863, Jan 13 2009, 10:26:13) 

>>> a={ 'a': 6, 'b': 1, 'c': 2 } 
>>> sorted(a.items(), key=lambda (key,value): value) 
[('b', 1), ('c', 2), ('a', 6)] 

W języku Python 3 wyrażenie lambda będzie musiało zostać zmienione na lambda x: x[1].

+0

Możesz usunąć pierwsze trzy linie, a ostatnie ... wygląda na trochę zajętego. –

+1

Pamiętaj, że rozpakowywanie krotek nie jest już obsługiwane w Pythonie 3 ... niestety. – Stephan202

+0

@Nikhil Myślę, że nagłówek jest ważny. Szczególnie w przypadku komentarza per @ Stephan, jest znacząca wersja, której używam do wersji demonstracyjnej. –

7

W przypadku programów innych niż Python 3, należy użyć iteritems, aby uzyskać wzrost wydajności generatorów, które generują wartości pojedynczo, zamiast zwracać wszystkie naraz.

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

Dla jeszcze większych słowników, możemy pójść o krok dalej i pełnią funkcję klucza be in C zamiast Python, jak to jest teraz z lambda.

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

Brawo!

+0

Oooh. Miło z operatorem.itemgetter. Słodkie. –

+0

Chociaż nie testowałem, jestem sceptyczny co do twierdzenia, że ​​"posortowane" działa lepiej na iteratorze materiałów eksploatacyjnych niż na liście. Domyślam się, że pierwszą rzeczą, którą posortowano, jest przeczytanie tego Iteratora na liście; bardzo niejasne jest, czy można tutaj uzyskać wzrost wydajności. –

4

Często może być bardzo przydatny w użyciu namedtuple. Na przykład, masz słownika imię i zdobyć i chcesz posortować „Wynik”:

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

sortowania z pierwszym najniższym wynikiem:

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

sortowania z najwyższym wynikiem pierwsze:

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

Kolejność "klucza" i "wartości" w wymienionych krotkach to (wartość, klucz), ale teraz możesz uzyskać nazwę i wynik, powiedzmy, drugi najlepszy gracz (indeks = 1) bardzo Pythonically w ten sposób:

player = best[1] 
    player.name 
     'Richard' 
    player.score 
     7 
Powiązane problemy