Відповіді:
Не перевіряв це дуже широко, але працює в 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)
>>>
Якщо ви звикли робити for key, value in d.iteritems(): ...
замість ітераторів, це все одно працюватиме з рішенням, наведеним вище
>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>> print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>
З Python 3.x використовуйте d.items()
замість d.iteritems()
повернення ітератора.
items()
створюється список і тому використовується пам'ять, тоді як iteritems()
по суті не використовує пам'ять. Що використовувати в основному, залежить від розміру словника. Крім того, автоматичний інструмент перетворення Python 2 в Python 3 ( 2to3
) автоматично піклується про перетворення з iteritems()
на items()
, тому не потрібно турбуватися з цього приводу.
collections.OrderedDict
потім ви сортуєте один раз і отримуєте елементи в упорядкованому порядку завжди.
iteritems()
не використовує пам'ять, все повинно бути втягнуто в пам'ять sorted()
, тому немає різниці між використанням items()
і iteritems()
тут пам'яттю.
items()
(у списку, поверненому items()
та в відсортованому списку) і лише один раз з iteritems()
(у відсортованому списку).
Використовуйте sorted()
функцію:
return sorted(dict.iteritems())
Якщо ви хочете фактичний ітератор над відсортованими результатами, оскільки sorted()
повертає список, використовуйте:
return iter(sorted(dict.iteritems()))
Клавіші диктанту зберігаються у хешшлеті так, що це їх "природний порядок", тобто psuedo-random. Будь-яке інше замовлення - це концепція споживача дикту.
sorted () завжди повертає список, а не дікт. Якщо ви передасте йому dict.items () (який створює список кортежів), він поверне список кортежів [(k1, v1), (k2, v2), ...], які можна використовувати у циклі певним чином дуже схожий на дикт, але це ніяк не дикт !
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)]
Далі виглядає, як диктант у циклі, але це не так, це список кортежів, які розпаковуються в k, v:
for k,v in sorted(foo.items()):
print k, v
Приблизно еквівалентний:
for k in sorted(foo.keys()):
print k, foo[k]
sorted(foo.keys())
краще як еквівалент sorted(foo)
, оскільки словники повертають свої ключі під час повторної повторення (з перевагою, якщо не змушувати створювати foo.keys()
проміжний список, можливо - залежно від того, як sorted()
реалізовано для ітерабелів).
k in sorted(foo.keys()):
яка тягне ключі або for k,v in sorted(foo.items()):
яка повертає копію списку пар словника, я б здогадавсяsorted(foo.keys())
Відповідь Грега правильна. Зауважте, що в Python 3.0 вам доведеться це зробити
sorted(dict.items())
як iteritems
не буде.
Тепер ви також можете використовувати OrderedDict
в Python 2.7:
>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
... ('second', 2),
... ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]
Тут ви знайдете нову сторінку для версії 2.7 та API OrрядDict .
Загалом, такий сорт можна сортувати так:
for k in sorted(d):
print k, d[k]
Для конкретного випадку у запитанні, маючи "крапку заміни" для d.iteritems (), додайте функцію типу:
def sortdict(d, **opts):
# **opts so any currently supported sorted() options can be passed
for k in sorted(d, **opts):
yield k, d[k]
і так закінчується рядок змінюється від
return dict.iteritems()
до
return sortdict(dict)
або
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)
Цей метод все ще має сортування O (N log N), однак після короткого лінійного перетину він видає елементи в упорядкованому порядку, як це йде, що робить його теоретично більш ефективним, коли не завжди потрібен весь список.
Якщо ви хочете сортувати за порядком, щоб елементи були вставлені замість порядку клавіш, вам слід ознайомитись із колекціями Python.OrderedDict . (Тільки для Python 3)
сортування повертає список, отже, ваша помилка, коли ви намагаєтесь повторити його, але оскільки ви не можете замовити дік, вам доведеться мати справу зі списком.
Я поняття не маю, що є більшим контекстом вашого коду, але ви можете спробувати додати ітератор до результату. як це, можливо ?:
return iter(sorted(dict.iteritems()))
звичайно, ви отримаєте назад кортежі зараз, тому що сортування перетворило ваш малюнок у список кортежів
наприклад: скажіть, що ваш дикт був:
{'a':1,'c':3,'b':2}
сортування перетворює його у список:
[('a',1),('b',2),('c',3)]
тож коли ви насправді перейдете до списку, ви отримаєте назад (у цьому прикладі) кортеж, що складається з рядка та цілого числа, але принаймні ви зможете перебрати його.
Якщо припустити, що ви використовуєте CPython 2.x і маєте великий словник моїх вироків, то використання сортованого (мій вирок) буде повільним, оскільки сортування створює відсортований список ключів мого вироку.
У цьому випадку ви можете подивитися на мій пакет sorteddict
упорядкованих вироків, який включає реалізацію C у C. Особливо, якщо вам доведеться кілька разів перебирати відсортований список ключів на різних етапах (тобто кількість елементів) життя словників.
.items()
замістьiteritems()
: як сказав @Claudiu, iteritems не працює для Python 3.x, алеitems()
доступний з Python 2.6.