web-dev-qa-db-fra.com

Itérer un certain nombre de fois sans enregistrer le numéro d'itération n'importe où

Je me demandais s'il était possible d'effectuer un certain nombre d'opérations sans stocker le numéro d'itération de la boucle n'importe où.

Par exemple, disons que je veux imprimer deux "hello" messages à la console. En ce moment, je sais que je peux faire:

for i in range(2):
    print "hello"

mais alors la variable i va prendre les valeurs 0 et 1 (dont je n'ai pas vraiment besoin). Existe-t-il un moyen de réaliser la même chose sans stocker ces valeurs indésirables n'importe où?

44
BorrajaX

L'idiome (partagé par plusieurs autres langues) pour une variable inutilisée est un seul trait de soulignement _. Les analyseurs de code ne se plaindront généralement pas de _ étant inutilisé, et les programmeurs sauront instantanément que c'est un raccourci pour i_dont_care_wtf_you_put_here. Il n'y a aucun moyen d'itérer sans avoir une variable d'élément - comme le Zen de Python le dit, "les cas spéciaux ne sont pas assez spéciaux pour enfreindre les règles").

46
user395760
exec 'print "hello";' * 2

devrait fonctionner, mais j'ai honte d'avoir pensé à ça.

pdate: Je viens de penser à un autre:

for _ in " "*10: print "hello"
15
recursive

Eh bien, je pense que la boucle que vous avez fournie dans la question est à peu près aussi bonne que possible, mais je tiens à souligner que les variables inutilisées qui doivent être affectées peuvent être affectées à la variable nommée _, une convention pour "rejeter" la valeur attribuée. Bien que le _ référence conservera la valeur que vous lui avez donnée, les linters de code et les autres développeurs comprendront que vous n'utilisez pas cette référence. Voici donc un exemple:

for _ in range(2):
    print('Hello')
10
ThorSummoner

D'autres ont résolu l'incapacité à éviter complètement une variable d'itération dans une boucle for, mais il existe des options pour réduire le travail un tout petit peu. range doit générer un tas de nombres après tout, ce qui implique une petite quantité de travail; si vous voulez éviter cela, vous pouvez utiliser itertools.repeat pour obtenir la même valeur (ignorée) encore et encore, ce qui n'implique aucune création/récupération d'objets différents:

from itertools import repeat

for _ in repeat(None, 200):  # Runs the loop 200 times
    ...

Cela fonctionnera plus rapidement dans les repères microbiens que for _ in range(200):, mais si le corps de la boucle fait un travail significatif, c'est une goutte dans le compartiment. Et contrairement à la multiplication d'une séquence anonyme pour votre boucle itérable, repeat n'a qu'un coût de configuration trivial, sans surcharge de mémoire dépendant de la longueur.

5
ShadowRanger

Bien que je sois entièrement d'accord avec la réponse de Delnan, ce n'est pas impossible:

loop = range(NUM_ITERATIONS+1)
while loop.pop():
    do_stuff()

Notez, cependant, que cela ne fonctionnera pas pour une liste arbitraire: si la première valeur de la liste (la dernière sautée) n'évalue pas en False, vous obtiendrez une autre itération et une exception lors de la prochaine passe : IndexError: pop from empty list. De plus, votre liste (loop) sera vide après la boucle.

Juste pour la curiosité. ;)

4
Walter

Vous pouvez simplement faire
imprimer 2 * 'bonjour'

1
sairam546

Désolé, mais pour itérer sur n'importe quoi dans n'importe quelle langue, Python et anglais inclus, un index doit être stocké. Que ce soit dans une variable ou non. Trouver un moyen de masquer le fait que = python suit en interne la boucle for ne changera pas le fait qu'elle est. Je recommande de la laisser telle quelle.

1
user3399731

Cela imprimera 'bonjour' 3 fois sans stocker i...

[print('hello') for i in range(3)]
1
Rasmus Pedersen
for Word in ['hello'] * 2:
    print Word

Ce n'est pas du Python idiomatique, mais ce que vous essayez de faire n'est pas non plus.

0
nmichaels