Как вызвать функцию дважды или более раз подряд?

Есть ли короткий способ вызвать функцию дважды или более подряд в Python? Например:

do()
do()
do()

может быть, как:

3*do()

Ответы

Ответ 1

Я бы:

for _ in range(3):
    do()

_ - это соглашение для переменной, значение которой вам неинтересно.

Вы также можете увидеть, как некоторые люди пишут:

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

однако это немного дороже, потому что он создает список, содержащий возвращаемые значения для каждого вызова do() (даже если он None), а затем выбрасывает полученный список. Я бы не предложил использовать это, если вы не используете список возвращаемых значений.

Ответ 2

Вы можете определить функцию, которая повторяет переданную функцию N раз.

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

Если вы хотите сделать его еще более гибким, вы можете даже передать аргументы повторяемой функции:

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

Использование:

>>> 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!

Ответ 3

Простой для цикла?

for i in range(3):
  do()

Или, если вы заинтересованы в результатах и ​​хотите их собрать, с бонусом быть 1 лайнером:

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

Ответ 4

Еще три способа сделать это:

(I) Я думаю, что использование map также может быть вариантом, хотя это требует генерации дополнительного списка с None в некоторых случаях и всегда нуждается в списке аргументов:

def do():
    print 'hello world'

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

(II) itertools содержат функции, которые можно использовать для перебора и других функций https://docs.python.org/2/library/itertools.html

(III) Использование списков функций не упоминалось до сих пор, я думаю (и это фактически самый близкий по синтаксису к первоначально обсужденному):

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

Или как один лайнер:

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

Ответ 5

Мои два цента:

from itertools import repeat 

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

Ответ 6

Вот подход, который не требует использования цикла for или определения промежуточной функции или лямбда-функции (а также однострочного). Метод объединяет следующие две идеи:

Объединяя их, мы получаем:

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

(Идея передать object(), поскольку отправитель приходит из этого одобренного ответа на переполнение стека.)

И вот как это выглядит в интерактивной подсказке:

>>> def do():
...   print("called")
... 
>>> next(itertools.islice(iter(do, object()), 3, 3), None)
called
called
called

Ответ 7

from itertools import repeat, starmap

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

Смотрите repeatfunc рецепт из модуля itertools, который на самом деле намного более мощный. Если вам нужно просто вызвать метод, но не заботятся о возвращаемых значениях, вы можете использовать его в цикле for:

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

но это становится уродливым.

Ответ 8

Вы можете попробовать цикл while, как показано ниже;

def do1():
    # Do something

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

do2(5)

Таким образом, вызовите функцию do1 5 раз.

Ответ 9

Вы можете использовать itertools.repeat с operator.methodcaller для вызова метода __call__ функции N раз. Вот пример функции генератора, делающей это:

from itertools import repeat
from operator import methodcaller


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

Пример использования:

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]