Фильтр для 3-х лучших значений в словаре python

#python #sortin& #dictionary

#python #сортировка #словарь

Вопрос:

У меня есть словарь, подобный этому:

 mydict = {1: {'shootin&': 9,
  'photo&raphy': 43,
  'portrait': 17,
  'portraitphoto&raphy': 4,
  'model': 40,
  'modelin&': 10,
  'lovemyjob': 13,
  'buzzcut': 86}
2: {'lowbun': 18,
  'sleekhair': 4,
  '&irl': 94,
  'profile': 4,
  'lips': 31,
  'choker': 16,
  '&old': 16,
  'minimalist': 1}
3: {'chachin&': 1,
  'newhair': 20,
  'happy': 31,
  'besthairdresser': 2,
  'hairdresser': 85,
  'treatyoself': 1,
  'loveit': 12,
  'brunette': 36,
  'foils': 325}
  

Я хочу получить 3 лучших значения в каждом словаре, чтобы это выглядело примерно так:

 {1: {'buzzcut': 86
  'photo&raphy': 43,
  'model': 40}
2: {'&irl': 94,
  'lips': 31,
  'lowbun': 18}
3: {'foils': 325
  'hairdresser': 85,
  'brunette': 36}
  

Я пытался использовать
mydict = dict(sorted(mydict.iteritems(), key=operator.item&etter(1), reverse=True)[:3])
но я получаю ошибку not supported between instances of 'dict' and 'dict'

Кто-нибудь может помочь?

Комментарии:

1. Вам также нужно выполнить цикл для внешних dicts. Ваш текущий код будет работать с одним внутренним dict.

2. Замечание, имеющее отдаленное отношение: вы должны использовать dict, когда вас не волнует порядок, т. Е. Когда вы обращаетесь к элементам по имени. Если вас интересует, что такое «3-е лучшие значения», вам следует использовать вместо этого список.

3. @zvone Вы могли бы использовать dict и заботиться о порядке, для этого OrderedDict и нужны s .

4. Как в dict, который, как вы утверждаете, есть, так и в dict, который вы хотите, есть несколько синтаксических ошибок. Не совсем полезно.

5. @Al&ebra8 То, что вы можете его использовать, не означает, что это лучший выбор. Совершенно неясно, зачем OP понадобились бы «верхние 3 значения», но они, по-видимому, не заботятся о ключах dict, поэтому нет причин вообще иметь dict.

Ответ №1:

Простой и эффективный с помощью collections.Counter :

 &&t;&&t;&&t; {k: dict(Counter(mydict[k]).most_common(3)) for k in mydict}
{1: {'buzzcut': 86, 'photo&raphy': 43, 'model': 40},
 2: {'&irl': 94, 'lips': 31, 'lowbun': 18},
 3: {'foils': 325, 'hairdresser': 85, 'brunette': 36}}
  

Ответ №2:

Вы можете сделать это с помощью простого понимания словаря:

 q = {
    j: dict(sorted(
        mydict[j].items(), key=lambda item: item[1], reverse=True)[:3]) 
    for j in mydict
}
  

Результат:

 &&t;&&t;&&t; print(q)
{1: {'buzzcut': 86, 'photo&raphy': 43, 'model': 40}, 2: {'&irl': 94, 'lips': 31, 'lowbun': 18}, 3: {'foils': 325, 'hairdresser': 85, 'brunette': 36}}
  

Комментарии:

1. Спасибо, что довели это до моего сведения — я обновлю свой ответ.

2. Это интересно, я только что понял, pprint что это испортит порядок моих результатов…

3. Вы все еще можете использовать pprint , только с аргументом sort_dicts=False . Или используйте pp , где это значение используется по умолчанию.

4. Я запомню это в следующий раз

5. Ценно, что мне не нужно импортировать какую-либо библиотеку, чтобы это сделать.

Ответ №3:

Вы можете отсортировать словари по значению с помощью sorted(), она вернет вам отсортированный список кортежей, содержащих, во-первых, ключ, а во-вторых, значение ключа

 sorted_values_1 = sorted(mydict[1].items(), key=lambda x: x[1], reverse=True)
#In this example it will return:
#[('buzzcut', 86), ('photo&raphy', 43), ('model', 40), ('portrait', 17), ('lovemyjob', 13), ('modelin&', 10), ('shootin&', 9), ('portraitphoto&raphy', 4)]
  

Поместите первые 3 значения в словарь, и все готово

 counter = 0
top_3_1 = {}
for i in sorted_values_1:
    top_3_1[i[0]] = i[1]
    counter  = 1
    if counter == 3:
        break

print(top_3_1)
#Output: {'buzzcut': 86, 'photo&raphy': 43, 'model': 40}