2009-03-23 8 views
14

У меня есть словарь, как:Как выполнить итерацию по словарю Python, упорядоченному по значениям?

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

я хотел бы итерацию над ней по значению, а не ключом. Иными словами:

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

Что является самым простым способом?

+0

дублировать http://stackoverflow.com/questions/613183/sort-a-dictionary-in-python-by-the-value –

+2

Не простофиля. Другой хочет сортировать словарь, что невозможно. Я хочу перебирать словарь в отсортированном порядке. – mike

+0

и код в точности то же самое. – SilentGhost

ответ

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

для них из вас ненавидящие лямбда :-)

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

Однако operator версия требует CPython 2.5+

+0

Мне нужны ключи и предметы, а не только предметы. – mike

+0

dictionary.items() дает вам как ключи, так и значения, а не только клавиши. –

+1

@Mike: элементы (ключ, значение). – vartec

3

Метод items дает список (ключ, значение) кортежи, которые могут быть отсортированы с использованием sorted и специального ключа сортировки:

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)] 

В Python 3 выражение лямбда должно быть изменено на lambda x: x[1].

+0

Возможно, вы захотите удалить первые три строки и последний ... теперь выглядит немного занятым. –

+1

Обратите внимание, что распаковка кортежей больше не поддерживается в Python 3 ... к сожалению. – Stephan202

+0

@Nikhil Я думаю, что заголовок важен. Особенно за комментарий @ Stephan, значительная версия, которую я использую для демонстрации. –

7

Для программ, отличных от Python 3, вы захотите использовать iteritems для повышения производительности генераторов, которые дают значения по одному за раз, а не сразу возвращать их все.

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

Для еще больших словарей, мы можем пойти дальше и иметь функцию ключа be in C вместо Python, как это прямо сейчас с лямбда.

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

Hooray!

+0

Oooh. Приятно с operator.itemgetter. Милая. –

+0

Хотя я не тестировал, я скептически отношусь к утверждению, что 'sorted' лучше работает на расходуемом итераторе, чем в списке. Я бы предположил, что самое первое, что «отсортировано», прочитано, что итератор в списке в любом случае; это очень неясно, есть ли производительность, которую можно получить, здесь. –

4

Часто бывает полезно использовать namedtuple. Например, у вас есть словарь имя и оценка, и вы хотите отсортировать по «счет»:

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) 

Порядок «ключ» и «значение» в перечисленных кортежах (значение, ключ), но теперь вы можете получить имя и оценку, скажем, второго лучшего игрока (index = 1) очень Pythonically

player = best[1] 
    player.name 
     'Richard' 
    player.score 
     7 
Смежные вопросы