Itération sur les dictionnaires à l'aide de boucles «for»
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
...
Comment Python reconnaît-il qu'il lui suffit de lire la clé du dictionnaire? La clé est-elle un mot spécial en Python? Ou s'agit-il simplement d'une variable?
Ce ne sont pas que des for
boucles. Le mot important ici est "itérer".
Un dictionnaire est un mappage des clés aux valeurs:
d = {'x': 1, 'y': 2, 'z': 3}
Chaque fois que nous itérons dessus, nous itérons sur les touches. Le nom de la variable key
est uniquement destiné à être descriptif - et il est tout à fait approprié pour le but.
Cela se produit dans une liste de compréhension:
>>> [k for k in d]
['x', 'y', 'z']
Cela se produit lorsque nous passons le dictionnaire à list (ou tout autre objet de type collection):
>>> list(d)
['x', 'y', 'z']
La façon dont Python itère est, dans un contexte où il le faut, il appelle la __iter__
méthode de l'objet (dans ce cas le dictionnaire) qui retourne un itérateur (dans ce cas, un objet keyiterator):
>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>
Nous ne devrions pas utiliser ces méthodes spéciales nous-mêmes, mais utiliser la fonction intégrée respective pour l'appeler iter
:
>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>
Itérateurs ont une __next__
méthode - mais nous appelons avec la fonction builtin, next
:
>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Lorsqu'un itérateur est épuisé, il augmente StopIteration
. C'est ainsi que Python sait quitter une for
boucle, ou une compréhension de liste, ou une expression de générateur, ou tout autre contexte itératif. Une fois qu'un itérateur lève, StopIteration
il le relèvera toujours - si vous voulez recommencer, vous en avez besoin d'un nouveau.
>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']
Retour aux dict
Nous avons vu des dits itérer dans de nombreux contextes. Ce que nous avons vu, c'est que chaque fois que nous répétons un dict, nous obtenons les clés. Retour à l'exemple d'origine:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
Si nous changeons le nom de la variable, nous obtenons toujours les clés. Essayons:
>>> for each_key in d:
... print(each_key, '=>', d[each_key])
...
x => 1
y => 2
z => 3
Si nous voulons parcourir les valeurs, nous devons utiliser la .values
méthode des dicts, ou pour les deux ensemble .items
:
>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]
Dans l'exemple donné, il serait plus efficace d'itérer sur les éléments comme celui-ci:
for a_key, corresponding_value in d.items():
print(a_key, corresponding_value)
Mais à des fins académiques, l'exemple de la question est très bien.