web-dev-qa-db-fra.com

Trier le dictionnaire des listes par paires de valeurs clés

J'essaie de trier les valeurs qui se trouvent dans un dictionnaire de listes et d'en créer une nouvelle. Voici les données:

{
    'fbi': [229, 421, 586, 654, 947, 955, 1095, 1294, 1467, 2423, 3063, 3478, 3617, 3730, 3848, 3959, 4018, 4136, 4297, 4435, 4635, 4679, 4738, 5116, 5211, 5330, 5698, 6107, 6792, 6906, 7036], 
    'comey': [605, 756, 1388, 1439, 1593, 1810, 1959, 2123, 2506, 3037, 6848], 
    'hillary': [14, 181, 449, 614, 704, 1079, 1250, 2484, 2534, 2659, 3233, 3374, 3488, 3565, 4076, 4756, 4865, 6125, 7109]
}

Ce que j'essaie, c'est de trouver les 20 plus petites valeurs dans celles-ci et d'obtenir une liste de leurs clés correspondantes. Par exemple, les trois premières valeurs les plus faibles sont 14 (hillary), 181 (hillary) et 229 (fbi). Par conséquent, comment puis-je obtenir une liste comme celle-ci:

['hillary', 'hillary', 'fbi']

Toutes les valeurs seront toujours différentes. De plus, toutes les valeurs de la liste sont triées, de croissant à décroissant.

Voici ce que j'ai essayé:

for m in range(1,20):
    for i in sort_vals.values():
        if i[0] < a[0]:
            a[0] = i[0]

Cela me donne la moindre valeur mais pas une autre car après une itération, la moindre valeur est toujours la même. Je suppose que si je peux supprimer cette valeur particulière, ce sera utile. Je ne peux penser à rien d'autre. Merci!

17
Shawn

Vous pouvez aplatir le dictionnaire (d ici) dans une liste de tuples avec le key/value paires et triez les tuples en fonction des valeurs:

from operator import itemgetter

l = [(k,i) for k,v in d.items() for i in v]
# [('fbi', 229), ('fbi', 421), ('fbi', 586), ('fbi', 654),...
list(Zip(*sorted(l, key=itemgetter(1))[:3]))[0]
# ('hillary', 'hillary', 'fbi')
16
yatu

vous pourriez

  1. inverser votre cartographie, créer un dictionnaire avec des nombres => liste de noms
  2. trier ce dictionnaire (comme Tuple)
  3. choisissez les 3 premiers articles

comme ça:

import collections

d = collections.defaultdict(list)
data = {'fbi': [229, 421, 586, 654, 947, 955, 1095, 1294, 1467, 2423, 3063, 3478, 3617, 3730, 3848, 3959, 4018, 4136, 4297, 4435, 4635, 4679, 4738, 5116, 5211, 5330, 5698, 6107, 6792, 6906, 7036], 'comey': [605, 756, 1388, 1439, 1593, 1810, 1959, 2123, 2506, 3037, 6848], 'hillary': [14, 181, 449, 614, 704, 1079, 1250, 2484, 2534, 2659, 3233, 3374, 3488, 3565, 4076, 4756, 4865, 6125, 7109]}

for k,vlist in data.items():
    for v in vlist:
        d[v].append(k)

result = [v[0] for k,v in sorted(d.items())[:3]]

print(result)

cela imprime:

['hillary', 'hillary', 'fbi']

notez que s'il y a plusieurs noms attachés à une valeur, ce code ne choisira que le premier (v[0])

12

Utilisez simplement la fonction lambda dans sorted ().

l = [(k,i) for k,v in d.items() for i in v]
res = [v[0] for v in sorted(l, key=lambda x: x[1])][:20]
3
Tristan_

Étant donné que toutes les valeurs de la liste sont triées, vous pouvez utiliser heapq.merge:

d = {
    'fbi': [229, 421, 586, 654, 947, 955, 1095, 1294, 1467, 2423, 3063, 3478, 3617, 3730, 3848, 3959, 4018, 4136, 4297, 4435, 4635, 4679, 4738, 5116, 5211, 5330, 5698, 6107, 6792, 6906, 7036], 
    'comey': [605, 756, 1388, 1439, 1593, 1810, 1959, 2123, 2506, 3037, 6848], 
    'hillary': [14, 181, 449, 614, 704, 1079, 1250, 2484, 2534, 2659, 3233, 3374, 3488, 3565, 4076, 4756, 4865, 6125, 7109]
}
import heapq
pairs = [[(k, i) for i in v] for k, v in d.items()]
sorted_pairs = heapq.merge(*pairs, key=lambda a: a[1])
smallest_num_you_want = 3
res = [next(sorted_pairs)[0] for i in range(smallest_num_you_want)]
0
LiuXiMin