Python, преобразуйте словарь в отсортированный список значением вместо ключа

У меня есть collections.defaultdict (интервал), который я создаю для проведения подсчета того, сколько раз ключ разоблачает в ряде данных. Я позже хочу быть в состоянии отсортировать его (очевидно, путем превращения его в список сначала) убывающим способом, заказанным с самыми высокими значениями сначала. Я создал свой словарь как следующее:

adict = defaultdict(int)

позже я делаю набор:

adict['someval'] += 1
adict['anotherval'] +=1
adict['someval'] += 1

Идеально после этого я хотел бы получить печать из:

someval => 2
anotherval => 1
16
задан randombits 16 December 2009 в 15:54
поделиться

7 ответов

Ключи dict, отсортированные в обратном порядке по соответствующим значениям, лучше всего получить как

sorted(adict, key=adict.get, reverse=True)

, поскольку вам нужны пары ключ / значение, вы можете работать с элементами, как предлагают все другие ответы, или (чтобы использовать изящный adict.get связанный метод вместо itemgetters или странных лямбда-выражений; -),

[(k, adict[k]) for k in sorted(adict, key=adict.get, reverse=True)]

Edit : с точки зрения производительности в этом нет ничего особенного:

$ python -mtimeit -s'adict=dict((x,x**2) for x in range(-5,6))' '[(k, adict[k]) for k in sorted(adict, key=adict.get, reverse=True)]'
100000 loops, best of 3: 10.8 usec per loop
$ python -mtimeit -s'adict=dict((x,x**2) for x in range(-5,6)); from operator import itemgetter' 'sorted(adict.iteritems(), key=itemgetter(1), reverse=True)'
100000 loops, best of 3: 9.66 usec per loop
$ python -mtimeit -s'adict=dict((x,x**2) for x in range(-5,6))' 'sorted(adict.iteritems(), key=lambda (k,v): v, reverse=True)'
100000 loops, best of 3: 11.5 usec per loop

Итак, решение на основе .get находится посередине по производительности между двумя items -содержащими решениями - немного медленнее, чем itemgetter , немного быстрее, чем лямбда . В «узких» случаях, когда эти доли микросекунд важны для вас, обязательно сосредоточьтесь на этом. В обычных случаях

38
ответ дан 30 November 2019 в 15:04
поделиться

Чтобы отсортировать словарь:

from operator import itemgetter

sorted(adict.iteritems(), key=itemgetter(1), reverse=True)
42
ответ дан 30 November 2019 в 15:04
поделиться

Просто отсортируйте полученный дикт по значениям:

for k, v in sorted(adict.items(), key=lambda kv: kv[1], reverse=True):
    print("%s => %s" % (k,v))
4
ответ дан 30 November 2019 в 15:04
поделиться

If you're using the newest python 2.7 alpha, then you can use the Counter class in collections module:

c = Counter()

c['someval'] += 1
c['anotherval'] += 1
c['someval'] += 1

print c.most_common()

prints in the correct order:

[('someval', 2), ('anotherval', 1)]

The code used on 2.7 is available already and there's a version adapted to 2.5. Perhaps you want to use it to stay forward compatible with the native stdlib version that is about to be released.

2
ответ дан 30 November 2019 в 15:04
поделиться
from collections import defaultdict
adict = defaultdict(int)

adict['a'] += 1
adict['b'] += 3
adict['c'] += 5
adict['d'] += 2

for key, value in sorted(adict.items(), lambda a, b: cmp(a[1], b[1]), reverse=True):
    print "%r => %r" % (key, value)

>>> 
'c' => 5
'b' => 3
'd' => 2
'a' => 1

2
ответ дан 30 November 2019 в 15:04
поделиться

«Инвертировать» словарь.

from collections import defaultdict
inv_dict = defaultdict( list )
for key, value in adict:
    inv_dict[value].append( key )
max_value= max( inv_dict.keys() )

Набор ключей с максимальным числом вхождений -

inv_dict[max_value] 

Набор ключей в порядке убывания их появления -

for value, key_list in sorted( inv_dict ):
    print key_list, value
0
ответ дан 30 November 2019 в 15:04
поделиться

Примечание: я помещаю это как ответ, чтобы его заметили. Я не хочу голосов. Если вы хотите проголосовать за кого-нибудь, проголосуйте за Надю.

, принятый в настоящее время ответ дает результаты по времени, которые основаны на тривиально небольшом наборе данных (size == 6 - (-5) == 11 ). Различия в стоимости различных методов маскируются накладными расходами. Такой вариант использования, как наиболее часто встречающиеся слова в тексте или наиболее частые имена в списке членства или переписи, включает гораздо большие наборы данных.

Повторение эксперимента с диапазоном (-n, n + 1) (Windows box, Python 2.6 .4, все время в микросекундах):

n = 5: 11,5, 9,34, 11,3
n = 50: 65,5, 46,2, 68,1
n = 500: 612, 423, 614

Эти результаты НЕ "немного" отличаются. Ответ itemgetter - явный победитель по скорости.

Также было упомянуто " простота получить идиому ". Сложим их вместе для удобства сравнения:

[(k, adict [k]) для k в отсортированном (adict, key = adict.get, reverse = True)] отсортированном (adict.iteritems (), key = itemgetter (1) , reverse = True)

Идиома get не только просматривает словарь дважды (как указал Дж. Ф. Себастьян), но и составляет один список (результат sorted () ) затем перебирает этот список, чтобы создать список результатов. Я бы назвал это барокко, а не простым . YMMV.

3
ответ дан 30 November 2019 в 15:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: