2008-12-12 6 views

Antwort

134

Habe das nicht sehr ausführlich getestet, funktioniert aber 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) 
>>> 

Wenn Sie zu tun for key, value in d.iteritems(): ... statt Iteratoren verwendet werden, wird dies noch mit der Lösung arbeiten über

>>> d = {"x":2, "h":15, "a":2222} 
>>> for key, value in sorted(d.iteritems()): 
>>>  print(key, value) 
('a', 2222) 
('h', 15) 
('x', 2) 
>>> 
+20

Verwenden Sie '.items()' anstelle von 'iteritems()': Wie @Claudiu sagte, funktioniert iteritems nicht für Python 3.x, aber 'items()' ist in Python 2.6 verfügbar. – Remi

+37

Dies ist nicht offensichtlich. Tatsächlich erstellt 'items()' eine Liste und verwendet daher Speicher, während 'iteritems()' im Wesentlichen keinen Speicher verwendet. Was zu verwenden ist, hängt hauptsächlich von der Größe des Wörterbuchs ab. Darüber hinaus kümmert sich das automatische Konvertierungswerkzeug Python 2 zu Python 3 ('2to3') automatisch um die Umwandlung von' iteritems() 'nach' items() ', so dass Sie sich darüber keine Gedanken machen müssen. – EOL

+0

Ist es möglich, es zu optimieren, wenn sowohl getitem als auch sortierte Iteration sehr häufig benötigt werden? – HoverHell

77

Verwenden Sie die sorted() Funktion:

return sorted(dict.iteritems()) 

Wenn Sie eine tatsächliche Iterator über die sortierten Ergebnisse wollen, da sorted() kehrt eine Liste, zu verwenden:

return iter(sorted(dict.iteritems())) 
+0

Das schlägt für mich fehl: : iter() hat non-iterator vom Typ 'list' zurückgegeben – mike

+0

Das liegt wahrscheinlich daran, dass Sie "dict" als Variablennamen verwenden. "dict" ist eigentlich der Typname von Wörterbüchern. Benutze einfach einen anderen Namen wie "mydict" hier und voila. –

+1

Funktioniert immer noch nicht. Sind Sie positiv? Sortierte() gibt einen anderen Iterator, im Gegensatz zu einer regulären Liste? – mike

28

Gregs Antwort ist richtig. Beachten Sie, dass in Python 3.0 Sie

sorted(dict.items()) 

als iteritems verschwunden sein zu tun haben.

+0

Das scheitert für mich: : iter() hat einen Nicht-Iterator vom Typ 'list' zurückgegeben – mike

+2

"Benutze keine Autos, weil wir in Zukunft Hoverboards haben werden" –

36

Die Schlüssel eines Diktats werden in einer Hashtabelle gespeichert, so dass ihre "natürliche Ordnung", d. H. Pseudozufällig, ist. Jede andere Bestellung ist ein Konzept des Verbrauchers des Diktats.

sortierte() gibt immer eine Liste, kein Diktat zurück. Wenn Sie eine dict.items() übergeben (die eine Liste von Tupeln erzeugt), wird eine Liste von Tupeln [(k1, v1), (k2, v2), ...] zurückgegeben, die in einer Schleife verwendet werden können in gewisser Weise wie ein Diktat, aber es ist nicht in jedem Fall ein Diktat!

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)] 

Die folgende fühlt sich wie ein dict in einer Schleife, aber es ist nicht, es ist eine Liste von Tupeln in k ausgepackt zu werden, v:

for k,v in sorted(foo.items()): 
    print k, v 

ungefähr äquivalent zu:

for k in sorted(foo.keys()): 
    print k, foo[k] 
+0

Okay, aber ich tu 'nicht Ich möchte ein Diktat oder eine Liste, ich möchte einen Iterator. Wie zwinge ich es dazu, ein Iterator zu sein? – mike

+2

'sorted (foo.keys())' ist besser als das Äquivalent 'sorted (foo)', da Wörterbücher ihre Schlüssel zurückgeben, wenn sie über iteriert werden (mit dem Vorteil, nicht das 'foo.keys()' intermediate erzeugen zu müssen) Liste, vielleicht - abhängig davon, wie 'sorted()' für iterables implementiert wird. – EOL

+0

Frage was besser ist für Geschwindigkeit und/oder Speicher 'k in sortierte (foo.keys()):' die die Schlüssel oder 'für k zieht, v in sortierte (foo.items()):' die eine Kopie von zurückgibt die Listenpaare des Wörterbuchs würde ich erraten 'sortierte (foo.keys())' – CrandellWS

3

sortiert gibt eine Liste, damit Sie Ihre Fehler, wenn Sie versuchen, über sie zu durchlaufen, Aber weil Sie kein Diktat bestellen können, müssen Sie sich mit einer Liste befassen.

Ich habe keine Ahnung, was der größere Kontext Ihres Codes ist, aber Sie könnten versuchen, einen Iterator zu der resultierenden Liste hinzuzufügen. so vielleicht?:

return iter(sorted(dict.iteritems())) 

natürlich werden Sie jetzt Tupel immer wieder, weil sortiert Ihre dict in eine Liste von Tupeln

ex gedreht: sagen Ihre dict war: {'a':1,'c':3,'b':2} es in eine Liste sortiert dreht:

[('a',1),('b',2),('c',3)] 

so, wenn Sie iterieren tatsächlich über die Liste, die Sie zurück (in diesem Beispiel) ein Tupel bestehend aus einem String und einer ganzen Zahl, aber zumindest Sie wil Ich kann darüber iterieren.

3

Wenn Sie nach der Reihenfolge sortieren möchten, in der Elemente anstelle der Reihenfolge der Schlüssel eingefügt wurden, sollten Sie sich Pythons collections.OrderedDict ansehen. (Nur Python 3)

2

Angenommen, Sie verwenden CPython 2.x und haben ein großes Wörterbuch mydict, dann wird die Verwendung von sorted (mydict) langsam sein, da sortierte eine sortierte Liste der Schlüssel von mydict erstellt.

In diesem Fall möchten Sie vielleicht mein ordereddict-Paket betrachten, das eine C-Implementierung von sorteddict in C enthält. Vor allem, wenn Sie die sortierte Liste von Schlüsseln mehrmals in verschiedenen Stadien durchlaufen müssen (dh Anzahl der Elemente) der Lebensdauer der Wörterbücher.

http://anthon.home.xs4all.nl/Python/ordereddict/

5

Generell man ein dict wie so sortieren kann:

for k in sorted(d): 
    print k, d[k] 

Für den speziellen Fall in der Frage, einen "Rückgang der Ersatz" für d.iteritems mit(), fügen eine Funktion wie:

def sortdict(d, **opts): 
    # **opts so any currently supported sorted() options can be passed 
    for k in sorted(d, **opts): 
     yield k, d[k] 

und so ändert sich die Endlinie von

return dict.iteritems() 

zu

return sortdict(dict) 

oder

return sortdict(dict, reverse = True) 
4
>>> 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) 

dieses Verfahren immer noch ein O hat (N log N) Sortieren, jedoch nach einer kurzen linearen heapify es die Elemente in sortierter ergibt Reihenfolge, wie es geht, macht es theoretisch effizienter, wenn Sie nicht immer die ganze Liste benötigen.

6

Sie können nun OrderedDict in Python 2.7 als auch verwenden:

>>> from collections import OrderedDict 
>>> d = OrderedDict([('first', 1), 
...     ('second', 2), 
...     ('third', 3)]) 
>>> d.items() 
[('first', 1), ('second', 2), ('third', 3)] 

Hier haben Sie die what's new Seite für Version 2.7 und der OrderedDict API.

Verwandte Themen