Réponses:
Je n'ai pas testé cela très largement, mais fonctionne en Python 2.5.2.
>>> d = {"x":2, "h":15, "a":2222}
>>> it = iter(sorted(d.iteritems()))
>>> it.next()
('a', 2222)
>>> it.next()
('h', 15)
>>> it.next()
('x', 2)
>>>
Si vous avez l'habitude de faire à la for key, value in d.iteritems(): ...
place des itérateurs, cela fonctionnera toujours avec la solution ci-dessus
>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>> print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>
Avec Python 3.x, utilisez d.items()
au lieu de d.iteritems()
pour renvoyer un itérateur.
items()
crée une liste et utilise donc de la mémoire, alors iteritems()
qu'essentiellement n'utilise pas de mémoire. Les éléments à utiliser dépendent principalement de la taille du dictionnaire. De plus, l'outil de conversion automatique Python 2 vers Python 3 ( 2to3
) prend automatiquement en charge la conversion de iteritems()
vers items()
, il n'y a donc pas lieu de s'inquiéter à ce sujet.
collections.OrderedDict
puis vous triez une fois et obtenez toujours les articles dans l'ordre trié.
iteritems()
n'utilise pas de mémoire, tout doit être mis en mémoire pour sorted()
, donc il n'y a pas de différence entre l'utilisation de items()
et iteritems()
ici en termes de mémoire.
items()
(dans la liste retournée par items()
, et dans la liste triée) et une seule fois avec iteritems()
(dans la liste triée uniquement).
Utilisez la sorted()
fonction:
return sorted(dict.iteritems())
Si vous voulez un véritable itérateur sur les résultats triés, puisque sorted()
renvoie une liste, utilisez:
return iter(sorted(dict.iteritems()))
Les clés d'un dict sont stockées dans une table de hachage de sorte que soit leur «ordre naturel», c'est-à-dire pseudo-aléatoire. Toute autre commande est un concept du consommateur du dict.
sorted () renvoie toujours une liste, pas un dict. Si vous lui passez un dict.items () (qui produit une liste de tuples), il retournera une liste de tuples [(k1, v1), (k2, v2), ...] qui peuvent être utilisés dans une boucle d'une manière très semblable à un dict, mais ce n'est en aucun cas un dict !
foo = {
'a': 1,
'b': 2,
'c': 3,
}
print foo
>>> {'a': 1, 'c': 3, 'b': 2}
print foo.items()
>>> [('a', 1), ('c', 3), ('b', 2)]
print sorted(foo.items())
>>> [('a', 1), ('b', 2), ('c', 3)]
Ce qui suit ressemble à un dict dans une boucle, mais ce n'est pas le cas, c'est une liste de tuples décompressés dans k, v:
for k,v in sorted(foo.items()):
print k, v
À peu près équivalent à:
for k in sorted(foo.keys()):
print k, foo[k]
sorted(foo.keys())
est mieux que l'équivalent sorted(foo)
, car les dictionnaires renvoient leurs clés lorsqu'ils sont itérés (avec l'avantage de ne pas être forcés de créer la foo.keys()
liste intermédiaire, peut-être - selon la façon dont sorted()
est implémenté les itérables).
k in sorted(foo.keys()):
qui tire les touches ou for k,v in sorted(foo.items()):
qui renvoie une copie des paires de listes du dictionnaire, je supposesorted(foo.keys())
La réponse de Greg est juste. Notez qu'en Python 3.0, vous devrez faire
sorted(dict.items())
comme iteritems
sera disparu.
Vous pouvez désormais également utiliser OrderedDict
Python 2.7:
>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
... ('second', 2),
... ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]
Vous avez ici la page Quoi de neuf pour la version 2.7 et l' API OrderedDict .
En général, on peut trier un dict comme ceci:
for k in sorted(d):
print k, d[k]
Pour le cas spécifique de la question, ayant un "drop in replacement" pour d.iteritems (), ajoutez une fonction comme:
def sortdict(d, **opts):
# **opts so any currently supported sorted() options can be passed
for k in sorted(d, **opts):
yield k, d[k]
et donc la ligne de fin change de
return dict.iteritems()
à
return sortdict(dict)
ou
return sortdict(dict, reverse = True)
>>> import heapq
>>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
>>> def iter_sorted(d):
keys = list(d)
heapq.heapify(keys) # Transforms to heap in O(N) time
while keys:
k = heapq.heappop(keys) # takes O(log n) time
yield (k, d[k])
>>> i = iter_sorted(d)
>>> for x in i:
print x
('a', 4)
('b', 9)
('c', 2)
('d', 8)
Cette méthode a toujours un tri O (N log N), cependant, après une courte segmentation linéaire, elle produit les éléments dans l'ordre trié au fur et à mesure, ce qui la rend théoriquement plus efficace lorsque vous n'avez pas toujours besoin de toute la liste.
Si vous souhaitez trier par ordre d'insertion des éléments au lieu de l'ordre des clés, vous devriez jeter un œil aux collections de Python . (Python 3 uniquement)
trié renvoie une liste, d'où votre erreur lorsque vous essayez de le parcourir, mais comme vous ne pouvez pas commander un dict, vous devrez traiter une liste.
Je n'ai aucune idée du contexte plus large de votre code, mais vous pouvez essayer d'ajouter un itérateur à la liste résultante. comme ça peut-être?:
return iter(sorted(dict.iteritems()))
bien sûr, vous récupérerez les tuples maintenant car triés a transformé votre dict en une liste de tuples
ex: dire que votre dict était:
{'a':1,'c':3,'b':2}
trié le transforme en une liste:
[('a',1),('b',2),('c',3)]
Ainsi, lorsque vous parcourez la liste, vous obtenez (dans cet exemple) un tuple composé d'une chaîne et d'un entier, mais au moins vous pourrez le parcourir.
En supposant que vous utilisez CPython 2.x et que vous disposez d'un grand dictionnaire mydict, l'utilisation de tri (mydict) va être lente car triée crée une liste triée des clés de mydict.
Dans ce cas, vous voudrez peut-être regarder mon paquet ordonné qui comprend une implémentation C de sorteddict
en C. Surtout si vous devez parcourir la liste triée de clés plusieurs fois à différentes étapes (c'est-à-dire le nombre d'éléments) de la durée de vie des dictionnaires.
.items()
place deiteritems()
: comme l'a dit @Claudiu, iteritems ne fonctionne pas pour Python 3.x, maisitems()
est disponible à partir de Python 2.6.