2010-02-13 6 views
3

J'ai un dictionnaire et une liste. Les valeurs des touches correspondent à celles de la liste, je vais juste essayer de savoir comment trier les valeurs dans le dictionnaire par les valeurs de la liste.Tri des clés du dictionnaire par valeurs dans une liste?

>>> l = [1, 2, 37, 32, 4, 3] 
>>> d = { 
    32: 'Megumi', 
    1: 'Ai', 
    2: 'Risa', 
    3: 'Eri', 
    4: 'Sayumi', 
    37: 'Mai' 
} 

J'ai essayé d'utiliser quelque chose le long des lignes de ...

>>> sorted(dict.keys(), key=list.index) 

... mais il est évident que renvoie uniquement les touches dans l'ordre souhaité.

(Aurait réalisé à 3h du matin que list et dict étaient horribles noms, je les ai changé pour l et d en conséquence.)

+0

vous un 3 comme une clé dict, mais il est pas dans la liste –

+0

Whoops, on dirait que je perdre de vue que. Merci! –

Répondre

4

Vous ne devriez pas vous appeler les variables dict et la liste, car alors, vous ne pouvez pas utiliser les méthodes de construction en plus . Je les ai renommés dans cet exemple.

>>> l = [1, 2, 37, 32, 4] 
>>> d = dict = { 
...  32: 'Megumi', 
...  1: 'Ai', 
...  2: 'Risa', 
...  3: 'Eri', 
...  4: 'Sayumi', 
...  37: 'Mai' 
... } 

Vous ne pouvez pas trier le type par défaut dict en Python, car il est une table de hachage et donc triée par les fonctions de hachage des clés. Quoi qu'il en soit, vous trouverez peut-être certaines implémentations de Python alternative lorsque vous recherchez OrderedDict ou quelque chose comme ça dans google.

Mais vous pouvez créer une nouvelle liste contenant les (clé, valeur) uplets du dictionnaire, qui est triée par la première liste:

>>> s = list((i, d.get(i)) for i in L) 
>>> print s 
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi')] 

Ou si vous ne souhaitez que les valeurs:

>>> s = list(d.get(i) for i in L) 
>>> print s 
['Ai', 'Risa', 'Mai', 'Megumi', 'Sayumi'] 

Hope that helps!

+0

Merci! J'ai fini par utiliser votre 2ème solution depuis que je viens de réaliser que je n'avais vraiment pas besoin des clés. :) –

1

Vous ne pouvez pas trier un dictionnaire car un dictionnaire n'est pas commandé.

Qu'est-ce que vous pouvez faire à la place:

  • obtenir toutes les paires clé-valeur du dictionnaire, les trier et les mettre dans une liste ou
  • ce que vous faites déjà: garder un tri liste des clés et utilisez le dictionnaire lorsque vous avez besoin de la valeur correspondant à une clé.
6

Ne pas les shadow builtins dict et list

>>> L = [1, 2, 37, 32, 4, 3] 
>>> D = { 
...  32: 'Megumi', 
...  1: 'Ai', 
...  2: 'Risa', 
...  3: 'Eri', 
...  4: 'Sayumi', 
...  37: 'Mai' 
... } 

# Seems roundabout to use sorted here 
# This causes an index error for keys in D that are not listed in L 
>>> sorted(D.items(), key=lambda x:L.index(x[0])) 
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi'), (3, 'Eri')] 
>>> 

# I think this is more direct than using sorted. 
# This also ignores/skips keys in D that aren't listed in L 
>>> [(i,D[i]) for i in L] 
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi'), (3, 'Eri')] 
>>> 
0

Classé dict est en fait une liste de 2-tuples, car en Python 2.x il ne dictionaty ordonné sommes intégrés. Vous avez presque la solution, il suffit d'ajouter une recherche de valeur après clés de tri:

[(k,dict[k]) for k in sorted(dict.keys(), key=list.index)] 

Mais cela échoue lorsqu'une touche est pas list. Ajoutons une modification de mettre toutes ces valeurs à la fin de sorte, classées par ordre décroissant:

def _index(x): # Allow non-full key list to be used in sorting 
    try: return (list.index(x), x) 
    except ValueError: return (sys.maxint, x) 

[(k,dict[k]) for k in sorted(dict.keys(), key=_index)] 
0

En Python 3.1, vous pouvez utiliser la classe OrderedDict:

from collections import OrderedDict 

l = [1, 2, 37, 32, 4] 
d = { 
    32: 'Megumi', 
    1: 'Ai', 
    2: 'Risa', 
    3: 'Eri', 
    4: 'Sayumi', 
    37: 'Mai' 
} 

def myindex(element): 
    try: 
     return l.index(element) 
    except ValueError: 
     return -1 # nonexisting keys are appended to the beginning of the list 

od = OrderedDict(sorted(d.items(), key = lambda t: myindex(t[0]))) 

print(od) 

Comme je ne savais pas ce que vous voulez faire avec les touches qui ne sont pas dans la liste, je reviens juste -1 dans ce cas, ce qui signifie sont ces éléments préfixé à la liste en quelque sorte (c'est-à-dire dans un ordre non stable).

Mon exemple imprimera

OrderedDict([(3, 'Eri'), (1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi')]) 
Questions connexes