В Python, как я перебираю словарь в отсортированном порядке?
Существует существующая функция, которая заканчивается на:
return dict.iteritems()
который возвращает несортированный итератор для данного словаря. Я хотел бы вернуть итератор, который просматривает элементы в отсортированном порядке. Как это сделать?
Ответы
Ответ 1
Не тестировал это очень подробно, но работает в 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)
>>>
Ответ 2
Используйте функцию sorted()
:
return sorted(dict.iteritems())
Если вам нужен фактический итератор по отсортированным результатам, так как sorted()
возвращает список, используйте:
return iter(sorted(dict.iteritems()))
Ответ 3
Диск-ключи хранятся в хеш-таблице, так что это их "естественный порядок", т.е. псевдо-случайный. Любой другой заказ - это понятие потребителя dict.
sorted() всегда возвращает список, а не dict. Если вы передадите ему файл 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)]
Следующее выглядит как dict в цикле, но это не так, это список кортежей, распакованных в k, v:
for k,v in sorted(foo.items()):
print k, v
Грубо эквивалентно:
for k in sorted(foo.keys()):
print k, foo[k]
Ответ 4
Ответ Грега прав. Обратите внимание, что в Python 3.0 вам придется делать
sorted(dict.items())
как iteritems
исчезнет.
Ответ 5
Теперь вы можете использовать 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 и OrderedDict API.
Ответ 6
В общем случае можно отсортировать 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)
Ответ 7
>>> 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), однако после короткого линейного heapify он дает элементы в отсортированном порядке по мере того, как это происходит, что делает его теоретически более эффективным, когда вам не всегда нужен весь список.
Ответ 8
sorted возвращает список, следовательно, ваша ошибка, когда вы пытаетесь перебрать его,
но поскольку вы не можете заказать диктофон, вам придется иметь дело со списком.
Я понятия не имею, что такое большой контекст вашего кода, но вы можете попробовать добавить
итератора к результирующему списку.
как это может быть?:
return iter(sorted(dict.iteritems()))
конечно, вы получите кортежи теперь, потому что отсортированный превратил ваш dict в список кортежей
например:
скажем, ваш дикт:
{'a':1,'c':3,'b':2}
sorted превращает его в список:
[('a',1),('b',2),('c',3)]
поэтому, когда вы на самом деле перебираете список, вы возвращаетесь (в этом примере) кортеж
состоящий из строки и целого числа, но по крайней мере вы сможете перебирать ее.
Ответ 9
Если вы хотите отсортировать по порядку, в котором элементы были вставлены вместо порядка ключей, вы должны взглянуть на Python collections.OrderedDict. (Только для Python 3)
Ответ 10
Предполагая, что вы используете CPython 2.x и имеете большой словарь mydict, то использование отсортированного (mydict) будет медленным, потому что отсортированный строит отсортированный список ключей mydict.
В этом случае вам может понадобиться посмотреть мой пакет orderdict, который включает реализацию C sorteddict
в C. Особенно, если вам нужно перебирать отсортированный список ключей несколько раз на разных этапах (то есть количество элементов ) времени жизни словарей.
http://anthon.home.xs4all.nl/Python/ordereddict/