Je rencontre des problèmes lorsque je dois utiliser une boucle while
ou une boucle for
en Python. Il semble que les gens préfèrent utiliser une boucle for
(moins de lignes de code?). Y a-t-il une situation spécifique que je devrais utiliser l'un ou l'autre? Est-ce une question de préférence personnelle? Les codes que j'ai lus jusqu'à présent m'ont fait penser qu'il y a de grandes différences entre eux.
Oui, il y a une énorme différence entre while et for.
L'instruction for parcourt une collection, un objet itérable ou une fonction de générateur.
L'instruction while boucle simplement jusqu'à ce qu'une condition soit False.
Ce n'est pas la préférence. Il s'agit de savoir quelles sont vos structures de données.
Souvent, nous représentons les valeurs que nous voulons traiter sous la forme d'un range
(une liste réelle) ou xrange
(qui génère les valeurs). Cela nous donne une structure de données sur mesure pour l'instruction for.
En général, cependant, nous avons une collection prête à l'emploi: un ensemble, un tuple, une liste, une carte ou même une chaîne est déjà une collection itérable, nous utilisons donc simplement une boucle for.
Dans certains cas, nous pourrions souhaiter qu'un traitement de programmation fonctionnelle soit fait pour nous, auquel cas nous pouvons appliquer cette transformation dans le cadre de l'itération. Les fonctions sorted
et enumerate
appliquent une transformation sur un itérable qui correspond naturellement à l'instruction for.
Si vous n'avez pas de structure de données bien ordonnée à parcourir, ou si vous n'avez pas de fonction de générateur qui pilote votre traitement, vous devez utiliser while.
while
est utile dans les scénarios où la condition de rupture ne dépend logiquement d'aucune sorte de séquence. Par exemple, envisagez des interactions imprévisibles:
while user_is_sleeping():
wait()
Bien sûr, vous pourriez écrire un itérateur approprié pour encapsuler cette action et la rendre accessible via for
- mais comment cela servirait-il la lisibilité? ¹
Dans tous les autres cas en Python, utilisez for
(ou une fonction d'ordre supérieur appropriée qui encapsule la boucle).
¹ en supposant que le user_is_sleeping
la fonction renvoie False
lorsqu'elle est fausse, l'exemple de code peut être réécrit comme la boucle for
suivante:
for _ in iter(user_is_sleeping, False):
wait()
Le for
est le choix le plus Pythonique pour itérer une liste car il est plus simple et plus facile à lire.
Par exemple ceci:
for i in range(11):
print i
est beaucoup plus simple et plus facile à lire que ceci:
i = 0
while i <= 10:
print i
i = i + 1
Tout d'abord, il existe des différences entre la boucle for dans python et dans d'autres langages. Alors qu'en python elle itère sur une liste de valeurs (par exemple: pour la valeur dans [4,3,2,7]), dans la plupart des autres langages (C/C++, Java, PHP etc), il agit comme une boucle while, mais plus facile à lire.
Les boucles For sont généralement utilisées lorsque le nombre d'itérations est connu (la longueur d'un tableau par exemple), tandis que les boucles sont utilisées lorsque vous ne savez pas combien de temps cela prendra (par exemple, sort de bulle = algorithme qui boucle tant que les valeurs ne sont pas triées)
Pensez à traiter les itérables. Vous pouvez le faire avec une boucle for
:
for i in mylist:
print i
Ou, vous pouvez le faire avec une boucle while
:
it = mylist.__iter__()
while True:
try:
print it.next()
except StopIteration:
break
Ces deux blocs de code font fondamentalement la même chose de la même manière. Mais la boucle for
masque la création de l'itérateur et la gestion de l'exception StopIteration
afin que vous n'ayez pas à les gérer vous-même.
La seule fois où je peux penser que vous utiliseriez une boucle while
pour gérer un itérable serait si vous aviez besoin d'accéder directement à l'itérateur pour une raison quelconque, par exemple dans certaines circonstances, vous devez ignorer les éléments de la liste.
Pour les boucles, il est généralement plus clair ce que fait l'itération. Vous ne pouvez pas toujours les utiliser directement, mais la plupart du temps, la logique d'itération avec la boucle while peut être enveloppée dans une fonction de générateur. Par exemple:
def path_to_root(node):
while node is not None:
yield node
node = node.parent
for parent in path_to_root(node):
...
Au lieu de
parent = node
while parent is not None:
...
parent = parent.parent