Максимум среди последних элементов списка

Хотелось бы сформировать список suff, содержащий максимум от текущего элемента до конца списка l1 через генератор. Использование max(l1[i:]) будет неэффективно при больших размерах списка. Вариант метода скользящего окна удалось только в обычный цикл поместить.

l1 = [6,4,11,15,7,2]   
suff = [0 for i in range(len(l1)]
suff[-1] = l1[-1]
for i in range(2, len(l1)):
    suff[-i] = max(l1[-i], suff[-i+1])

Ответы (3 шт):

Автор решения: CrazyElf

Если я вас правильно понял, то можно сделать вот так:

lst = [6, 4, 11, 15, 7, 2]   
suff = [y := x if not i else max(x, y) for i, x in enumerate(lst[::-1])][::-1]
print(suff)
# [15, 15, 15, 15, 7, 2]

Но при этом придётся:

  • Использовать моржовый оператор :=
  • Дважды переворачивать список - и до и после генерации спискового сокращения

Максимум чего можно добиться чисто генераторами:

gen = (y := x if not i else max(x, y) for i, x in enumerate(reversed(lst)))

Но потом результат всё-равно придётся переворачивать, а для этого преобразовывать генератор в список.

P.S. Укороченная комбинированная версия, спасибо комментаторам. )

lst = [6, 4, 11, 15, 7, 2]   
y = lst[-1]
gen = (y := max(x, y) for x in reversed(lst))
print(list(gen)[::-1])
# [15, 15, 15, 15, 7, 2]
→ Ссылка
Автор решения: Fox Fox
import os
import time
import random

# Создаём список из 1 миллиона случайных натуральных чисел
lst = [random.randint(1, 1000000) for _ in range(1000000)]
#lst = [6, 4, 11, 15, 7, 2]

def max_suffix_list(lst):
    # Используем генератор для создания списка suff
    y = lst[-1]
    suff = [y := max(x, y) for x in reversed(lst)][::-1]
    return suff

# Измеряем время выполнения
start_time = time.time()
result = max_suffix_list(lst)
end_time = time.time()

# Выводим результат и время выполнения
print(f"Результат: {result[:10]}...")  # Выводим первые 10 элементов результата для проверки
print(f"Время выполнения: {end_time - start_time} секунд")

print("\nНажмите любую клавишу для продолжения...")
os.system("pause > nul" if os.name == "nt" else "read > /dev/null")

Результат: [1000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000]...
Время выполнения: 0.057697296142578125 секунд
→ Ссылка
Автор решения: Stanislav Volodarskiy

itertools.accumulate позволяет вычислить накопительный максимум суффиксов массива.

import itertools

l1 = [6,4,11,15,7,2]   
suff = list(itertools.accumulate(reversed(l1), max))[::-1]
→ Ссылка