Как заставить timeit.Timer () работать с выводом itertools.starmap () - PullRequest
0 голосов
/ 31 марта 2020

Мне трудно обернуть голову, почему я могу заставить timeit.Timer() работать с выводом из functools.partial(), но не с выводом из itertools.starmap().

Что мне в основном нужно, это starmap(func, tuples) иметь те же «атрибуты», что и partial(func, one_arg_only), но быть более общим в том смысле, что я могу фактически передать в забавные c несколько аргументов одновременно.

Какой самый простой обходной путь здесь? Я попытался timeit.Timer(starmap(func,tuples)) и, очевидно, получил пресловутую ошибку:

ValueError: stmt is neither a string nor callable

Я предполагаю, что это вывод coz starmap не вызывается. Но как мне обойти это?

1 Ответ

1 голос
/ 31 марта 2020

Функция itertools.starmap() возвращает тип itertools.starmap повторяемый , тогда как functools.partial() возвращает тип functools.partial вызываемый . timeit.Timer() ожидает, что первым аргументом будет callable (или строка, которую он может exec()).

>>> type(itertools.starmap(lambda *args: list(args), [(1, 2)])
itertools.starmap
>>> type(functools.partial(lambda x: x+1, 1))
functools.partial

Что вы хотите сделать, это создать вызываемый элемент, который исчерпает итеративное значение, возвращаемое itertools.starmap. Один из способов сделать это - вызвать функцию list() на выходе карты звездного неба:

# This is the function to call
>>> example_func = lambda *args: len(args)

# This is the iterable that can call the example_func
>>> func_callers = itertools.starmap(example_func, [(1, 2)])

# This is the callable that actually processes func_callers
>>> execute_callers = lambda: list(func_callers)

# And finally using the timer
>>> timeit.Timer(execute_callers)
...