web-dev-qa-db-fra.com

Comment appeler une fonction deux fois ou plus consécutivement?

Existe-t-il un moyen rapide d'appeler une fonction deux fois ou plus consécutivement en Python? Par exemple:

do()
do()
do()

peut-être comme:

3*do()
34
alwbtc

Je voudrais:

for _ in range(3):
    do()

Le _ Est la convention pour une variable dont vous ne vous souciez pas de la valeur.

Vous pourriez également voir certaines personnes écrire:

[do() for _ in range(3)]

cependant, c'est un peu plus cher car il crée une liste contenant les valeurs de retour de chaque appel de do() (même si c'est None), puis jette la liste résultante. Je ne suggérerais pas d'utiliser ceci à moins que vous soyez en utilisant la liste des valeurs de retour.

62
Greg Hewgill

Vous pouvez définir une fonction qui répète la fonction passée N fois.

def repeat_fun(times, f):
    for i in range(times): f()

Si vous voulez le rendre encore plus flexible, vous pouvez même passer des arguments à la fonction en cours de répétition:

def repeat_fun(times, f, *args):
    for i in range(times): f(*args)

Usage:

>>> def do():
...   print 'Doing'
... 
>>> def say(s):
...   print s
... 
>>> repeat_fun(3, do)
Doing
Doing
Doing
>>> repeat_fun(4, say, 'Hello!')
Hello!
Hello!
Hello!
Hello!
11
juliomalegria

Trois autres façons de le faire:

(I) Je pense que l'utilisation de map peut également être une option, bien que cela nécessite la génération d'une liste supplémentaire avec Nones dans certains cas et nécessite toujours une liste d'arguments:

def do():
    print 'hello world'

l=map(lambda x: do(), range(10))

(II) itertools contient des fonctions qui peuvent également être utilisées pour parcourir d'autres fonctions https://docs.python.org/2/library/itertools.html

(III) L'utilisation de listes de fonctions n'était pas mentionnée jusqu'à présent je pense (et c'est en fait la syntaxe la plus proche de celle discutée à l'origine):

it=[do]*10
[f() for f in it]

Ou en tant que doublure:

[f() for f in [do]*10]
5
VDV

Une boucle simple pour?

for i in range(3):
  do()

Ou, si vous êtes intéressé par les résultats et que vous souhaitez les collecter, avec le bonus d'être un liner:

vals = [do() for _ in range(3)]
5
g.d.d.c

Mes deux centimes:

from itertools import repeat 

list(repeat(f(), x))  # for pure f
[f() for f in repeat(f, x)]  # for impure f
4
Joffer

Voici une approche qui ne nécessite pas l'utilisation d'une boucle for ou la définition d'une fonction intermédiaire ou d'une fonction lambda (et est également une ligne). La méthode combine les deux idées suivantes:

  • appeler la fonction intégrée iter() avec l'argument sentinelle facultatif, et

  • en utilisant la itertools recette pour faire avancer un itérateur n étapes (voir la recette de consume()).

Ensemble, nous obtenons:

next(islice(iter(do, object()), 3, 3), None)

(L'idée de passer object() comme sentinelle vient de this réponse Stack Overflow acceptée.)

Et voici à quoi cela ressemble dans l'invite interactive:

>>> def do():
...   print("called")
... 
>>> next(itertools.islice(iter(do, object()), 3, 3), None)
called
called
called
3
cjerdonek
from itertools import repeat, starmap

results = list(starmap(do, repeat((), 3)))

Voir la recette repeatfunc du module itertools qui est en fait beaucoup plus puissante. Si vous devez simplement appeler la méthode mais ne vous souciez pas des valeurs de retour, vous pouvez l'utiliser dans une boucle for:

for _ in starmap(do, repeat((), 3)): pass

mais ça devient moche.

1
Mr_and_Mrs_D

Vous pouvez essayer la boucle while comme indiqué ci-dessous;

def do1():
    # Do something

def do2(x):
    while x > 0:
        do1()
        x -= 1

do2(5)

Faites donc appeler la fonction do1 5 fois.

0
Alphard

Vous pouvez utiliser itertools.repeat avec operator.methodcaller pour appeler le __call__ méthode de la fonction [~ # ~] n [~ # ~] fois. Voici un exemple d'une fonction générateur qui le fait:

from itertools import repeat
from operator import methodcaller


def call_n_times(function, n):
    yield from map(methodcaller('__call__'), repeat(function, n))

Exemple d'utilisation:

import random
from functools import partial

throw_dice = partial(random.randint, 1, 6)
result = call_n_times(throw_dice, 10)
print(list(result))
# [6, 3, 1, 2, 4, 6, 4, 1, 4, 6]
0
Georgy