Odpowiedzi:
Nie testowałem tego bardzo dokładnie, ale działa w Pythonie 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)
>>>
Jeśli jesteś przyzwyczajony do robienia for key, value in d.iteritems(): ...
zamiast iteratorów, nadal będzie to działać z powyższym rozwiązaniem
>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>> print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>
W Pythonie 3.x użyj d.items()
zamiast, d.iteritems()
aby zwrócić iterator.
items()
tworzy listę i dlatego używa pamięci, podczas gdy iteritems()
zasadniczo nie używa pamięci. Czego używać zależy głównie od wielkości słownika. Ponadto automatyczne narzędzie do konwersji Python 2 na Python 3 ( 2to3
) automatycznie zajmuje się konwersją z iteritems()
na items()
, więc nie musisz się tym martwić.
collections.OrderedDict
następnie sortujesz raz i zawsze otrzymujesz przedmioty w posortowanej kolejności.
iteritems()
nie używa pamięci, wszystko musi zostać wciągnięte do pamięci sorted()
, więc nie ma różnicy między użytkowaniem items()
i iteritems()
tutaj pod względem pamięci.
items()
(na liście zwróconej przez items()
i na posortowanej liście) i tylko raz za pomocą iteritems()
(tylko na posortowanej liście).
Użyj sorted()
funkcji:
return sorted(dict.iteritems())
Jeśli chcesz rzeczywistego iteratora nad posortowanymi wynikami, ponieważ sorted()
zwraca listę, użyj:
return iter(sorted(dict.iteritems()))
Klucze dykta są przechowywane w tablicy hasht, więc jest to ich „naturalny porządek”, tzn. Psuedo-random. Każde inne zamówienie jest koncepcją konsumenta dykta.
sorted () zawsze zwraca listę, a nie dykt. Jeśli przekażesz mu dict.items () (który tworzy listę krotek), zwróci listę krotek [(k1, v1), (k2, v2), ...], których można użyć w pętli w sposób bardzo podobny do dykt, ale w żadnym wypadku nie jest to dykt !
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)]
Poniższe wygląda jak dykta w pętli, ale tak nie jest, to lista krotek rozpakowywanych do k, v:
for k,v in sorted(foo.items()):
print k, v
Z grubsza odpowiada:
for k in sorted(foo.keys()):
print k, foo[k]
sorted(foo.keys())
jest lepszy jako odpowiednik sorted(foo)
, ponieważ słowniki zwracają klucze po zakończeniu iteracji (z tą zaletą, że może nie być zmuszone do utworzenia foo.keys()
listy pośredniej, w zależności od sposobu sorted()
implementacji iteracji).
k in sorted(foo.keys()):
która wyciąga klucze lub for k,v in sorted(foo.items()):
która zwraca kopię par listy słownika, zgadujęsorted(foo.keys())
Możesz teraz używać również OrderedDict
w Pythonie 2.7:
>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
... ('second', 2),
... ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]
Tutaj masz nową stronę dla wersji 2.7 i interfejs API OrdersDict .
Zasadniczo można sortować taki dyktat:
for k in sorted(d):
print k, d[k]
W konkretnym przypadku w pytaniu, mając „spadek zastępowania” dla d.iteritems (), dodaj funkcję:
def sortdict(d, **opts):
# **opts so any currently supported sorted() options can be passed
for k in sorted(d, **opts):
yield k, d[k]
i tak zmienia się linia końcowa
return dict.iteritems()
do
return sortdict(dict)
lub
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)
Ta metoda wciąż ma sortowanie O (N log N), jednak po krótkim liniowym rozsypywaniu zwraca elementy w posortowanej kolejności, dzięki czemu teoretycznie jest bardziej wydajna, gdy nie zawsze potrzebujesz całej listy.
sorted zwraca listę, stąd błąd, gdy próbujesz iterować nad nią, ale ponieważ nie możesz zamówić nagrania, będziesz musiał poradzić sobie z listą.
Nie mam pojęcia, jaki jest większy kontekst twojego kodu, ale możesz spróbować dodać iterator do wynikowej listy. może tak ?:
return iter(sorted(dict.iteritems()))
oczywiście będziesz teraz wracał krotki, ponieważ posortowane zmieniło twój dyktat w listę krotek
np. powiedz, że twój dykt:
{'a':1,'c':3,'b':2}
posortowany zamienia go w listę:
[('a',1),('b',2),('c',3)]
więc kiedy faktycznie wykonasz iterację po liście, otrzymasz (w tym przykładzie) krotkę złożoną z łańcucha i liczby całkowitej, ale przynajmniej będziesz w stanie iterować po niej.
Zakładając, że używasz CPython 2.x i masz duży słownik mydict, to użycie sortowania (mydict) będzie wolne, ponieważ sortowane tworzy posortowaną listę kluczy mydict.
W takim przypadku możesz zajrzeć do mojego pakietu uporządkowanego, który zawiera implementację C sorteddict
w C. Szczególnie, jeśli musisz wielokrotnie przeglądać posortowaną listę kluczy na różnych etapach (tj. Liczbie elementów) życia słowników.
.items()
zamiastiteritems()
: jak powiedział @Claudiu, iterity nie działają dla Python 3.x, aleitems()
są dostępne z Python 2.6.