Comme la plupart des langages, Python
a des boucles for. La seule raison pour laquelle
vous ne les avez pas vues jusqu’à maintenant est que
Python sait faire tellement d’autre choses
que vous n’en avez pas besoin aussi souvent.
La plupart des autres langages n’ont pas de type de données liste
aussi puissant que celui de Python, vous êtes
donc amené à faire beaucoup de travail à la main, spécifier un début,
une fin et un pas pour définir une suite d’entiers ou de caractères ou
d’autres entités énumérables. Mais en Python
une boucle for parcourt simplement une liste, de la
même manière que les list
comprehensions fonctionnent.
Exemple 6.8. Présentation des boucles for
>>> li = ['a', 'b', 'e']>>> for s in li:... print sa
b
e>>> print"\n".join(li)a
b
e
La syntaxe d’une boucle for est similaire
aux list
comprehensions. li est
une liste et s prend successivement la valeur
de chaque élément, en commençant par le premier.
Comme une instruction if ou n’importe
quel autre bloc
indenté, une boucle for peut contenir
autant de lignes de codes que vous le voulez.
Voici la raison pour laquelle vous n’aviez pas encore vu la
boucle for : nous n’en avions pas eu besoin.
C’est incroyable la fréquence à laquelle nous utilisons les
boucles for dans d’autres langages alors que ce
que nous voudrions vraiment et un join ou une
list comprehension.
Faire un compteur «normal» (selon les critères
de Visual Basic) pour la boucle for est également simple.
Exemple 6.9. Compteurs simples
>>> for i in range(5):... print i0
1
2
3
4>>> li = ['a', 'b', 'c', 'd', 'e']>>> for i in range(len(li)):... print li[i]a
b
c
d
e
Comme nous l’avons vu
dans l'Exemple 3.20, «Assignation de valeurs consécutives»,
range produit une liste d’entiers que nous
pouvons parcourir. Je sais que ça peut sembler étrange, mais c’est
parfois (et j’insiste sur le parfois) utile
d’avoir une boucle sur un compteur.
Ne faites jamais ça. C’est un style de pensée
Visual Basic. Libérez-vous en.
Parcourez simplement la liste comme dans l’exemple
précédent.
Les boucles for ne sont seulement faites pour les compteurs simples. Elles peuvent parcourir de nombreuses choses. Voici un exemple d'utilisation
d'une boucle for pour parcourir un dictionnaire.
Exemple 6.10. Parcourir un dictionnaire
>>> import os>>> for k, v in os.environ.items():... print"%s=%s" % (k, v)USERPROFILE=C:\Documents and Settings\mpilgrim
OS=Windows_NT
COMPUTERNAME=MPILGRIM
USERNAME=mpilgrim
[...snip...]>>> print"\n".join(["%s=%s" % (k, v)... for k, v in os.environ.items()])USERPROFILE=C:\Documents and Settings\mpilgrim
OS=Windows_NT
COMPUTERNAME=MPILGRIM
USERNAME=mpilgrim
[...snip...]
os.environ est un dictionnaire des
variables d’environnement définies dans votre système. Sous
Windows ce sont vos variables utilisateur et système. Sous
UNIX ce sont les variables exportées par le
script de démarrage de votre shell. Sous MacOS il n’y a pas de notion de variables
d’environnement, ce dictionnaire est donc vide.
os.environ.items() retourne une liste de
tuples : [(key1,
value1),
(key2,
value2), ...]. La boucle
for parcourt cette liste. A la première
itération, il assigne
key1 à
k et
value1 à
v, donc k =
USERPROFILE et v =
C:\Documents and Settings\mpilgrim. A la
seconde, k reçoit la deuxième clé,
OS et v la valeur
correspondante, Windows_NT.
Avec l’assignement
multiple de variable et les list
comprehensions, vous pouvez entièrement
remplacer la boucle for par une seule
instruction. Le choix d’une des deux formes dans votre code est
une question de style personnel. J’aime ce style parce qu’il rend
clair que ce que nous faisons est une mutation d’un dictionnaire
en une liste, puis de joindre cette liste en une chaîne unique.
D’autres programmeurs préfèrent la forme de la boucle
for. Notez que la sortie est la même dans les
deux cas, bien que cette version-ci soit légèrement plus rapide
car il n’y a qu’une instruction print au lieu
d’une par itération.
Maintenant nous pouvons examiner l'usage de la boucle for dans la classe MP3FileInfo du programme d'exemple fileinfo.py présenté au Chapitre 5.
tagDataMap est un attribut de classe qui
définit les balises que nous recherchons dans un fichier
MP3 file. Les balises sont stockées dans des
champ de longueur fixe, une fois que nous avons lu les derniers
128 octets du fichier, les octets 3 à 32 contiennent toujours le
titre de la chanson, 33-62 le nom de l’artiste, 63-92 le nom de
l’album etc. Notez que tagDataMap est un
dictionnaire de tuples et que chaque tuple contient deux entiers
et une référence de fonction.
Ceci à l’air compliqué, mais ne l’est pas. La structure des
variables de for correspond à la structure des
éléments de la liste retournée par items.
Rappelez-vous, items retourne une liste de
tuples de la forme (key,
value). Le premier élément de
cette liste est ("title", (3, 33, <function
stripnulls>)), donc à la première itération de la
boucle tag reçoit "title",
start reçoit 3,
end reçoit 33 et
parseFunc reçoit la fonction
stripnulls.
Maintenant que nous avons extrait tous les paramètres pour
une balise MP3 unique, sauvegarder les données de
la balise data est simple. Nous découponstagdata de start à
end pour obtenir les véritables données de
cette balise, nous appelons parseFunc pour le
traitement final des données et assignons le résultat comme valeur
de la clé tag dans le pseudo-dictionnaire
self. Après itération de tous les éléments de
tagDataMap, self a les
valeurs de toutes les balises et vous savez à quoi ça
ressemble.