Risposte:
Non l'ho testato molto ampiamente, ma funziona in 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)
>>>
Se sei abituato a fare for key, value in d.iteritems(): ...
invece degli iteratori, funzionerà comunque con la soluzione sopra
>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>> print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>
Con Python 3.x, utilizzare d.items()
invece di d.iteritems()
restituire un iteratore.
items()
crea un elenco e quindi utilizza la memoria, mentre iteritems()
essenzialmente non utilizza la memoria. Cosa usare dipende principalmente dalle dimensioni del dizionario. Inoltre, lo strumento di conversione automatica da Python 2 a Python 3 ( 2to3
) si occupa automaticamente della conversione da iteritems()
a items()
, quindi non è necessario preoccuparsene.
collections.OrderedDict
quindi ordina una volta e ottieni sempre gli oggetti in ordine.
iteritems()
non usa la memoria, tutto deve essere archiviato nella memoria sorted()
, quindi non c'è differenza tra l'uso di items()
e iteritems()
qui la memoria.
items()
(nell'elenco restituito da items()
e nell'elenco ordinato) e solo una volta con iteritems()
(solo nell'elenco ordinato).
Usa la sorted()
funzione:
return sorted(dict.iteritems())
Se si desidera un iteratore effettivo sui risultati ordinati, poiché sorted()
restituisce un elenco, utilizzare:
return iter(sorted(dict.iteritems()))
Le chiavi di un dict sono archiviate in una tabella hash in modo che sia il loro "ordine naturale", cioè psuedo-casuale. Qualsiasi altro ordinamento è un concetto del consumatore del dict.
sort () restituisce sempre un elenco, non un dict. Se lo passi a dict.items () (che produce un elenco di tuple), restituirà un elenco di tuple [(k1, v1), (k2, v2), ...] che possono essere utilizzate in un ciclo in un modo molto simile a un dict, ma non è comunque 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)]
Quanto segue sembra un dict in un ciclo, ma non lo è, è un elenco di tuple che vengono decompresse in k, v:
for k,v in sorted(foo.items()):
print k, v
Praticamente equivalente a:
for k in sorted(foo.keys()):
print k, foo[k]
sorted(foo.keys())
è meglio come equivalente sorted(foo)
, poiché i dizionari restituiscono le loro chiavi quando ripetono (con il vantaggio di non essere costretti a creare l' foo.keys()
elenco intermedio, forse - a seconda di come sorted()
è implementato per gli iterabili).
k in sorted(foo.keys()):
che tira i tasti o for k,v in sorted(foo.items()):
che restituisce una copia delle coppie dell'elenco del dizionario, immaginosorted(foo.keys())
Ora puoi usare anche OrderedDict
in Python 2.7:
>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
... ('second', 2),
... ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]
Qui hai la pagina delle novità per la versione 2.7 e l' API OrderedDict .
In generale, si può ordinare un dict in questo modo:
for k in sorted(d):
print k, d[k]
Per il caso specifico nella domanda, avendo un "drop in sostituzione" per d.iteritems (), aggiungi una funzione come:
def sortdict(d, **opts):
# **opts so any currently supported sorted() options can be passed
for k in sorted(d, **opts):
yield k, d[k]
e così la linea di fine cambia da
return dict.iteritems()
per
return sortdict(dict)
o
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)
Questo metodo ha ancora un ordinamento O (N log N), tuttavia, dopo una breve heapify lineare, restituisce gli oggetti in ordine ordinato, rendendolo teoricamente più efficiente quando non è sempre necessario l'intero elenco.
Se vuoi ordinare in base all'ordine in cui gli elementi sono stati inseriti anziché l'ordine delle chiavi, dovresti dare un'occhiata alle collezioni di Python.OrderedDict . (Solo Python 3)
ordinati restituisce un elenco, quindi l'errore quando si tenta di scorrere su di esso, ma poiché non è possibile ordinare un dict, è necessario gestire un elenco.
Non ho idea di quale sia il contesto più ampio del tuo codice, ma potresti provare ad aggiungere un iteratore all'elenco risultante. così forse ?:
return iter(sorted(dict.iteritems()))
ovviamente ora tornerai alle tuple perché ordinate ha trasformato il tuo dict in un elenco di tuple
es: dire che il tuo dict era:
{'a':1,'c':3,'b':2}
ordinato lo trasforma in un elenco:
[('a',1),('b',2),('c',3)]
quindi quando si esegue l'iterazione effettiva dell'elenco si ritorna (in questo esempio) una tupla composta da una stringa e un numero intero, ma almeno si sarà in grado di scorrere su di essa.
Supponendo che tu stia utilizzando CPython 2.x e abbia un dizionario di grandi dimensioni mydict, l'utilizzo di sort (mydict) sarà lento perché ordinato crea un elenco ordinato delle chiavi di mydict.
In tal caso, potresti voler esaminare il mio pacchetto ordereddict che include un'implementazione C di sorteddict
in C. Specialmente se devi esaminare più volte l'elenco ordinato di chiavi in diverse fasi (es. Numero di elementi) della vita dei dizionari.
.items()
invece diiteritems()
: come diceva @Claudiu, iteritems non funziona per Python 3.x, maitems()
è disponibile da Python 2.6.