Quelle est la façon la plus pythonique d'itérer sur OrderedDict

J'ai un OrderedDict et dans une boucle je veux obtenir index, key et value. Il peut être fait de plusieurs façons, c'est à dire

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

Mais je voudrais éviter range(Len(A)) et raccourcir un.iterkeys(), un.itervalues() à quelque chose comme un.iteritems(). Avec énumérer et iteritems il est possible de reformuler comme

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

Mais il faut déballer à l'intérieur du corps de la boucle. Existe-t-il un moyen de décompresser dans une déclaration for ou peut-être un moyen plus élégant d'itérer?

25
demandé sur falsetru 2015-06-25 12:22:45

3 réponses

, Vous pouvez utiliser un tuple déballage dans for déclaration de:

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

Note Latérale:

En Python 3.x, Utilisation dict.items() qui renvoie une vue de dictionnaire itérable.

>>> for i, (key, value) in enumerate(d.items()):
...     print(i, key, value)
49
répondu falsetru 2015-06-25 23:52:08
$ 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

Est moche, si vous me demandez.

Je ne sais pas pourquoi êtes-vous intéressé par l'index. L'idée entre dict est que vous devez ignorer l'index. Il y a beaucoup de logique derrière dict et les files d'attente afin que nous soyons libres d'index.

Si vous insistez pour obtenir l'index, il n'est pas nécessaire d'itérer deux fois.

Voyons ce que enumerate fait aux listes:

>>> 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')]

Notez le "début".

Énumérer sait comment gérer les listes. Les dictionnaires stockent les données comme une liste, quelque part dans le ventre de la bête. Alors, que se passe-t-il si nous utilisons enumerate sur un dict?

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

Dans cette lumière, j'irais pour l'élégant:

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

Je sens que "pour i, (k, v) in" expose trop de la structure intérieure trop tôt. Avec "for i, k in" Nous sommes protégés et quand le temps vient de refactoriser, nous n'avons pas besoin de toucher la façon dont nous bouclons. Nous devons changer seulement ce que nous faisons dans la boucle. Un aspect de moins à prendre en charge.

Sans oublier que cet appel à énumérer fonctionne de la même manière dans n'importe quel python après 2.6:)

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

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

2
répondu Andrei 2015-06-25 14:14:04

Utiliser les méthodes values ou items pour obtenir un view, puis composer comme un iterator:

Par exemple pour trier par les valeurs dans votre dictionnaire

sorted(iter(my_dict.values()))
0
répondu SumNeuron 2016-12-04 12:29:08