Подтвердить что ты не робот

Какой самый питоновский путь для итерации по OrderedDict

У меня есть OrderedDict, и в цикле я хочу получить индекс, ключ и значение. Это можно сделать несколькими способами, то есть

a = collections.OrderedDict({…})
for i,b,c in zip(range(len(a)), a.iterkeys(), a.itervalues()):
  …

Но я бы хотел избежать диапазона (len (a)) и сократить a.iterkeys(), a.itervalues ​​() до чего-то вроде a.iteritems(). С перечислением и iteritems можно перефразировать как

for i,d in enumerate(a.iteritems()):
  b,c = d

Но для этого требуется распаковать внутри тела цикла. Есть ли способ распаковать в инструкции for или, может быть, более элегантный способ итерации?

4b9b3361

Ответ 1

Вы можете использовать распаковку в for statement:

for i, (key, value) in enumerate(a.iteritems()):
    # Do something with i, key, value

>>> d = {'a': 'b'}
>>> for i, (key, value) in enumerate(d.iteritems()):
...     print i, key, value
... 
0 a b

Боковое примечание:

В Python 3.x используйте dict.items(), который возвращает итеративный словарь.

>>> for i, (key, value) in enumerate(d.items()):
...     print(i, key, value)

Ответ 2

$ python
Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information. 
>>> import collections
>>> a = collections.OrderedDict({'a':'1','b':'2'})
>>> a
OrderedDict([('a', '1'), ('b', '2')])
>>> for i, (k,v) in enumerate(a.iteritems()):
...    print i, k, v
... 
0 a 1
1 b 2

Уродливо, если вы спросите меня.

Я не знаю, почему вас интересует индекс. Идея между dict заключается в том, что вы должны быть не осведомлены об индексе. Существует логика для dict и очередей, поэтому мы должны быть свободны от индексов.

Если вы настаиваете на получении индекса, нет необходимости повторять итерацию дважды.

Посмотрите, что перечисляет в списках:

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']    
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

Обратите внимание на "начало".

Enumerate знает, как управлять списками. Словари хранят данные как список, где-то в животе зверя. Итак, что произойдет, если мы будем использовать перечисление на dict?

>>> for i,k in enumerate(a):
...    print i,k
... 
0 a
1 b

В этом свете я бы пошел на элегантное:

>>> for i,k in enumerate(a):
...    print i,k,a[k]
... 
0 a 1
1 b 2

Я чувствую, что "для i, (k, v) в" слишком рано раскрывает слишком большую внутреннюю структуру. Поскольку "для i, k in" мы защищены, и когда время приходит к рефактору, нам не нужно прикасаться к тому, как мы зацикливаемся. Нам нужно изменить только то, что мы делаем в цикле. Еще один аспект, о котором нужно заботиться.

Не говоря уже о том, что этот вызов для перечисления работает одинаково на любом python после 2.6:)

https://docs.python.org/2/library/stdtypes.html#dict.iteritems

https://docs.python.org/2/library/functions.html#enumerate

Ответ 3

Используйте методы values или items, чтобы получить view, а затем введите его как iterator:

например. для сортировки по значениям в вашем словаре

sorted(iter(my_dict.values()))