Как вызвать функцию дважды или более раз подряд? - PullRequest
32 голосов
/ 28 января 2012

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

do()
do()
do()

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

3*do()

Ответы [ 9 ]

58 голосов
/ 28 января 2012

Я бы:

for _ in range(3):
    do()

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

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

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

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

11 голосов
/ 28 января 2012

Вы можете определить функцию, которая повторяет переданную функцию 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!
5 голосов
/ 15 марта 2016

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

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

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 голосов
/ 28 января 2012

Простой цикл?

for i in range(3):
  do()

Или, если вы заинтересованы в результатах и ​​хотите их получить, бонусом будет 1 вкладыш:

vals = [do() for _ in range(3)]
4 голосов
/ 14 января 2017

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

from itertools import repeat 

list(repeat(f(), x))  # for pure f
[f() for f in repeat(f, x)]  # for impure f
3 голосов
/ 28 октября 2016

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

  • вызов встроенной функции iter() с необязательным аргументом sentinel и

  • с использованием itertools рецепта для продвижения итератора n шагов (см. Рецепт для consume()).

Собрав их вместе, мы получим:

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
1 голос
/ 09 июня 2017
from itertools import repeat, starmap

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

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

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

но это уродливо.

0 голосов
/ 12 июня 2019

Вы можете использовать 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]
0 голосов
/ 10 мая 2017

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

def do1():
    # Do something

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

do2(5)

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

...