2015-06-25 4 views
21

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

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

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

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

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

ответ

46

Вы можете использовать кортеж распаковка в 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 

Side Примечание:

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

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

Почему вы рекомендуете использовать 'dict.items()' вместо этого? Он буквально строит новый список. – farukdgn

+0

@farukdgn, В Python 3.x, 'dict.items()' возвращает представление, а не список. И нет никаких «dict.iteritems» в Python 3.x. См. [Dictionary view] (https://docs.python.org/3/glossary.html#term-dictionary-view). – falsetru

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 заключается в том, что вы должны быть не осведомлены об индексе. Существует логика для диктата и очередей, чтобы мы были свободны от индексов.

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

Давайте посмотрим, что перечисление делает списки:

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

Я чувствую, что «я, (к, 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

+0

Мне нужен индекс для взаимодействия с компонентом, который знает порядок, но не интересуется именами. Я пытаюсь уменьшить число [], потому что для меня это не просто значение значения, а dict of dicts объектов, а некоторые объекты - массивы, и каждый [] больше болит в коде. И в какой-то момент я уже переработал все iterkeys для iteritems, где он сокращает код. В этом случае было бы более естественно использовать список dicts, но я предпочел бы иметь быстрый доступ к именам и сохранять однородность с другими объектами, которые являются чистыми dicts. –

+0

Для меня список диктонов предпочтительнее диктата dict, теперь это зависит от вашего конкретного случая. Он чувствует, что у вас есть объект Бога. – Andrei

0

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

например, сортировать по значкам в своем словаре

sorted(iter(my_dict.values()))