Для сравнения разных решений все ответы асимптоматически O (n).Здесь я сравнил три из них в jupyternotebook, используя магические функции %memit
и %timeit
:
import timeit
import random
%load_ext memory_profiler
l = list(range(100000)) # Create a long list
random.shuffle(l) # Let's shuffle the list
a = 50000 # Set the target variable the middle element
Вот функция, которая делает то, что хочет вопрос:
def max_less_than(a,l):
c = None
for i in l:
if i < a:
c = max(c,i) if c else i
return c
Здесьэто два решения, основанные на понимании списка и фильтрации:
result = max([x for x in l if x < a])
result = max(filter(lambda x: x < a, l))
Давайте профилируем их с помощью timeit
;Я запускал каждый из них по четыре раунда каждый раунд с 1000 итерациями, вы можете увеличить количество раундов / итераций для получения более точных результатов:
%timeit -n 1000 -r 4 max_less_than(a,l)
# 13.5 ms ± 588 µs per loop (mean ± std. dev. of 4 runs, 1000 loops each)
%timeit -n 1000 -r 4 max(filter(lambda x: x < a, l))
# 15.7 ms ± 248 µs per loop (mean ± std. dev. of 4 runs, 1000 loops each)
%timeit -n 1000 -r 4 max([x for x in l if x < a])
# 8.07 ms ± 301 µs per loop (mean ± std. dev. of 4 runs, 1000 loops each)
Кажется, что понимание списка превосходит два других показателя производительности процессора.Но давайте также проверим память:
%memit max_less_than(a,l)
# peak memory: 53.86 MiB, increment: 0.13 MiB
%memit max(filter(lambda x: x < a, l))
# peak memory: 53.75 MiB, increment: 0.12 MiB
%memit max([x for x in l if x < a])
# peak memory: 54.23 MiB, increment: 0.48 MiB
Причина, по которой основанный на фильтрах подход использует значительно меньше памяти, заключается в ее генераторной природе.В том смысле, что элементы объекта фильтра не будут храниться в памяти, но они оцениваются один за другим, когда над объектом выполняется какая-то операция.Итак, подведем итог: если ваша основная задача - эффективность памяти (например, в случаях, когда ваше решение требует многократного создания длинных последовательностей), вам лучше рассмотреть встроенные функции на основе генератора.