2012-10-14 7 views
0

J'ai besoin de trier un dictionnaire en fonction des clés, puis de renvoyer les valeurs associées à ces clés.Trier un dictionnaire en Python par les clés des valeurs

ages = {40 : 'mother', 38 : 'father', 17 : 'me'} 
['me', 'father', 'mother'] # Should return this 

Quel est le moyen le plus rapide possible de le faire (la performance est vraiment un problème pour moi, car le tri est appelé des milliers de fois dans mon code).

Merci beaucoup!

+2

Ce n'est pas valide la syntaxe de Python, et vous avez une clé c'est une chaîne. Est-ce une erreur? –

+1

Si le tri est appelé des milliers de fois dans votre code, vous souhaiterez peut-être mettre en cache certains des résultats ou utiliser un dictionnaire ordonné à la place. –

+1

Veuillez utiliser ':' pour séparer la clé: valeur. – kev

Répondre

4

Étant donné que vos clés sont numériques et par itérateurs par défaut sur les dictionnaires renvoient les clés - vous pouvez trier les clés directement:

>>> ages = {40:'mother', 38:'father', 17:'me'} 
>>> [ages[k] for k in sorted(ages)] 
['me', 'father', 'mother'] 
+0

Alors que techniquement il ne triera pas le dictionnaire, il donne la sortie voulue par OP. –

+0

Les dictionnaires ne sont pas "triables" par défaut. –

+0

@MarkusUnterwaditzer: Eh bien, le PO a demandé une sortie spécifique. Puisque cette réponse le fournit, je pense que c'est correct. – rubik

3

faisant usage des fonctions sorted() et zip():

zip(*sorted(ages.items(), key=lambda item: item[0]))[1] 

Première il trie le dictionnaire en créant une liste de tuples (les éléments):

>>> sorted(ages.items()) 
[(17, 'me'), (38, 'father'), (40, 'mother')] 

Ensuite, il ne prend que les valeurs:

>>> zip(*sorted(ages.items())[1] 
('me', 'father', 'mother') 

post-scriptum Si le dictionnaire est très grand, vous pouvez envisager d'utiliser dict.iteritems() qui, sur Python 2, renvoie un itérateur. Sur Python 3, il s'agit du comportement par défaut et il est fourni par dict.items().


solution alternative - en utilisant operator.itemgetter():

>>> import operator 
>>> operator.itemgetter(*sorted(ages))(ages) 
('me', 'father', 'mother') 
+0

'key = lambda item: item [0]' est la valeur par défaut, vous pouvez l'omettre en toute sécurité. – georg

+0

@ thg435: Bien sûr, merci de l'avoir signalé! – rubik

2

Vous ne pouvez pas trier un dictionnaire en raison de la nature de ce genre de collections. Bien que Python vous offre plusieurs options: soit utiliser OrderedDict (pour maintenir l'ordre de paires clé/valeur insérée), ou tout simplement trier les clés, par exemple ::

ages = {40 : 'mother', 38 : 'father', 17 : 'me'} 
ages_sorted = sorted(ages) 
# or ages.iterkeys()/.keys() (in Py3) which is a bit self-explanatory. 
+0

Vous n'avez pas besoin d'ajouter '.keys()', par défaut les dictionnaires sont itérés sur leurs clés. –

+0

True. Merci d'avoir corrigé. –

+0

D'autre part .keys()/.iterkeys() est un appel explicite qui donne une idée rapide du type de variable sur le côté gauche. –

Questions connexes