web-dev-qa-db-fra.com

Quel est le moyen le plus pythonique d’itérer OrderedDict?

J'ai un OrderedDict et dans une boucle, je veux obtenir un index, une clé et une valeur. C’est certain que cela peut se faire 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 a.iterkeys (), a.itervalues ​​() en quelque chose comme a.iteritems () . Avec énumération et itéritems, il est possible de reformuler

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

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

25
Askold Ilvento

Vous pouvez utiliser Tuple unpacking dans 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

Note latérale:

Dans Python 3.x, utilisez dict.items() qui retourne une vue dictionnaire itérable.

>>> for i, (key, value) in enumerate(d.items()):
...     print(i, key, value)
49
falsetru
$ 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-ce moche, si vous me demandez. 

Je ne sais pas pourquoi l’index vous intéresse ... L’idée entre dict est que vous devez ignorer l’indice ..__ Il y a toute une logique derrière les dict et les files d’attente pour que nous puissions être libre d'index.

Si vous insistez pour obtenir l'index, il n'est pas nécessaire de le répéter deux fois.

Voyons ce que énumère les 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".

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

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

Dans cette optique, je choisirais l'élégant:

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

Je pense que "pour i, (k, v) dans" expose trop tôt la structure interne trop tôt ... ". Avec" pour i, k in ", nous sommes protégés et lorsque le temps est venu de refactoriser, nous n'avons pas besoin toucher la façon dont nous bouclons. Nous devons seulement changer 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 tous les pythons après la version 2.6 :)

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

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

2
Andrei

Utilisez les méthodes values ou items pour obtenir un view, puis saisissez-le sous la forme iterator:

par exemple. trier par les valeurs de votre dictionnaire

sorted(iter(my_dict.values()))
0
SumNeuron