Как вызвать функцию дважды или более раз подряд?
Есть ли короткий способ вызвать функцию дважды или более подряд в 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]