Question

Est-il possible de suivre sans le i ?

for i in range(some_number):
    # do something

Si vous voulez juste faire quelque chose de N fois sans avoir besoin de l'itérateur.

Était-ce utile?

La solution

Sur le haut de ma tête, non.

Je pense que le mieux que vous puissiez faire est quelque chose comme ceci:

def loop(f,n):
    for i in xrange(n): f()

loop(lambda: <insert expression here>, 5)

Mais je pense que vous pouvez vivre avec la variable supplémentaire i .

Voici la possibilité d'utiliser la variable _ , qui n'est en réalité qu'une autre variable.

for _ in range(n):
    do_something()

Notez que le dernier résultat renvoyé dans une session python interactive est attribué à _ :

>>> 1+2
3
>>> _
3

Pour cette raison, je ne l'utiliserais pas de cette manière. Je ne suis au courant d'aucun idiome mentionné par Ryan. Cela peut gâcher votre interprète.

>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9

Et selon la Grammaire Python , il s'agit d'un nom de variable acceptable. :

identifier ::= (letter|"_") (letter | digit | "_")*

Autres conseils

Vous recherchez peut-être

for _ in itertools.repeat(None, times): ...

C’est LE moyen le plus rapide d’itérer fois fois en Python.

L'attribution générale à une valeur non utilisée consiste à lui attribuer un nom _ .

for _ in range(times):
    do_stuff()

Ce que tout le monde vous suggère d'utiliser _ ne dit pas que _ est fréquemment utilisé comme raccourci vers l'un des gettext , si vous voulez que votre logiciel soit disponible dans plusieurs langues, évitez de l'utiliser à d'autres fins.

import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')

Voici une idée aléatoire qui utilise (abuse?) le modèle de données ( lien Py3 ).

class Counter(object):
    def __init__(self, val):
        self.val = val

    def __nonzero__(self):
        self.val -= 1
        return self.val >= 0
    __bool__ = __nonzero__  # Alias to Py3 name to make code work unchanged on Py2 and Py3

x = Counter(5)
while x:
    # Do something
    pass

Je me demande s'il existe quelque chose comme cela dans les bibliothèques standard?

Vous pouvez utiliser _11 (ou un nombre ou un autre identifiant non valide) pour empêcher la coloration de noms avec gettext. Chaque fois que vous utilisez un trait de soulignement + identificateur non valide, vous obtenez un nom factice pouvant être utilisé dans la boucle for.

Peut-être que la réponse dépend du problème que vous rencontrez avec l’utilisation de l’itérateur? peut être utiliser

i = 100
while i:
    print i
    i-=1

ou

def loop(N, doSomething):
    if not N:
        return
    print doSomething(N)
    loop(N-1, doSomething)

loop(100, lambda a:a)

mais franchement, je ne vois aucun intérêt à utiliser de telles approches

t=0    
for _ in range(10):
    print t
    t = t+1

SORTIE:

0
1 
2 
3 
4 
5 
6 
7
8
9

Je suis généralement d’accord avec les solutions données ci-dessus. À savoir avec:

  1. Utilisation du trait de soulignement dans pour -loop (2 lignes et plus)
  2. Définition d'un compteur while normal (3 lignes et plus)
  3. Déclarer une classe personnalisée avec une implémentation __ non nulle __ (beaucoup plus de lignes)

Si vous voulez définir un objet comme dans # 3 , je vous recommanderais d'implémenter le protocole pour avec le mot clé ou appliquez contextlib .

De plus, je propose encore une autre solution. Il s’agit d’un 3-liner et n’est pas d’une élégance suprême, mais il utilise le package itertools et pourrait donc présenter un intérêt particulier.

from itertools import (chain, repeat)

times = chain(repeat(True, 2), repeat(False))
while next(times):
    print 'do stuff!'

Dans cet exemple, 2 correspond au nombre de fois où la boucle est répétée. chain encapsule deux répéteurs , le premier est limité mais le second est infini. Rappelez-vous que ce sont de vrais objets itérateurs, par conséquent, ils ne nécessitent pas de mémoire infinie. Évidemment, cela est beaucoup plus lent que la solution # 1 . Sauf si elle est écrite dans le cadre d’une fonction, elle peut nécessiter un nettoyage de la variable times .

Nous nous sommes amusés avec les éléments suivants, intéressants à partager donc:

class RepeatFunction:
    def __init__(self,n=1): self.n = n
    def __call__(self,Func):
        for i in xrange(self.n):
            Func()
        return Func


#----usage
k = 0

@RepeatFunction(7)                       #decorator for repeating function
def Job():
    global k
    print k
    k += 1

print '---------'
Job()

Résultats:

0
1
2
3
4
5
6
---------
7

Si do_something est une fonction simple ou peut être encapsulé dans une seule, une simple map () peut do_something ) fois:

# Py2 version - map is eager, so it can be used alone
map(do_something, xrange(some_number))

# Py3 version - map is lazy, so it must be consumed to do the work at all;
# wrapping in list() would be equivalent to Py2, but if you don't use the return
# value, it's wastefully creating a temporary, possibly huge, list of junk.
# collections.deque with maxlen 0 can efficiently run a generator to exhaustion without
# storing any of the results; the itertools consume recipe uses it for that purpose.
from collections import deque

deque(map(do_something, range(some_number)), 0)

Si vous souhaitez passer des arguments à do_something , vous pouvez également trouver le La recette itertools repeatfunc se lit bien:

Pour transmettre les mêmes arguments:

from collections import deque
from itertools import repeat, starmap

args = (..., my args here, ...)

# Same as Py3 map above, you must consume starmap (it's a lazy generator, even on Py2)
deque(starmap(do_something, repeat(args, some_number)), 0)

Pour passer différents arguments:

argses = [(1, 2), (3, 4), ...]

deque(starmap(do_something, argses), 0)

Au lieu d'un compteur inutile, vous avez maintenant une liste inutile. La meilleure solution consiste à utiliser une variable commençant par "_" qui indique aux vérificateurs de syntaxe que vous savez que vous n'utilisez pas la variable.

x = range(5)
while x:
  x.pop()
  print "Work!"

Si vous voulez vraiment éviter de mettre quelque chose avec un nom (une variable d'itération comme dans l'OP, ou une liste non désirée ou un générateur indésirable renvoyant la quantité de temps souhaitée), vous pouvez le faire si tu voulais vraiment:

for type('', (), {}).x in range(somenumber):
    dosomething()

Le truc utilisé est de créer une classe anonyme de type ('', (), {}) , ce qui donne une classe avec un nom vide, mais n'oubliez pas qu'elle n'est pas insérée dans le répertoire local. ou un espace de noms global (même si un nom non vide a été fourni). Ensuite, vous utilisez un membre de cette classe comme variable d'itération, ce qui est inaccessible, car la classe dont elle est membre est inaccessible.

#Return first n items of the iterable as a list
list(itertools.islice(iterable, n))

Tiré de http://docs.python.org/2/library/itertools. html

Qu'en est-il de:

while range(some_number):
    #do something
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top