#python #functional-programming #timeit
Вопрос:
Я пытаюсь подсчитать числа и слова в списке, используя две разные функции. В этом случае они оба генерируют правильный вывод. Но я всегда предполагал, что функциональный подход, использующий понимание списка, будет работать лучше, чем процедурный подход, использующий обычный цикл for. Когда я использую timeit для их сравнения, я не могу понять, почему функциональный подход на самом деле работает хуже. Не мог бы кто-нибудь, пожалуйста, провести меня сюда и объяснить, есть ли проблемы с моей реализацией?
test = [14242, 'A XUTFN UVG V UFI', 98, 80273, 'CKE', 'CPR']
def proc_counter(A):
nums = 0
wrds = 0
for i in A:
if type(i) == str:
wrds = len(i.split())
else:
nums = 1
return "Count of words = {} and Count of numbers = {}".format(wrds, nums)
proc_counter(test)
#'Count of words = 7 and Count of numbers = 3'
def func_counter(A):
lst = [0 if type(elem) == int else len(elem.split()) for elem in A]
nums = collections.Counter(lst)[0]
wrds = sum(lst)
return "Count of words = {} and Count of numbers = {}".format(wrds,nums)
func_counter(test)
#'Count of words = 7 and Count of numbers = 3'
%timeit proc_counter(test)
#1.15 µs ± 2.46 ns per loop
%timeit func_counter(test)
#2.26 µs ± 14.5 ns per loop
Комментарии:
1. Потому что ваш функциональный код создает список и счетчик (словарь), что требует времени. Кроме того, он обрабатывает пустые строки, как если бы они были целыми числами, что может быть проблемой.
2. @Michaelsczesny, похоже, это не так. Я также пробовал использовать список, состоящий из 500 элементов.
3. @jonrsharpe в списке не может быть пустых строк (я написал отдельную функцию для создания списков)
4. Ваша вторая функция должна повторить список три раза (построение списка, подсчет и суммирование), ваша первая функция-только один раз.
5. В дополнение к комментарию Щесны python разработан и оптимизирован для императивного кода, и он не поставляется со средствами для эффективной обработки неизменяемости/чистоты.