Найти в Дзене

Задача 9. Домашнее задание

Предлагаю посмотреть, как скучную задачу на циклы можно решить с помощью готовых функций на Python. Читаем условие: По сути мы видим здесь две отдельных задачи, у которых лишь общие входные данные. Это накладывает единственное незначительное ограничение, что при решении одной задачи нельзя менять входные данные. Например, если бы мы первую часть решали с помощью сортировки массива и суммы некоторого его суффикса (ведь именно там находились бы положительные числа). Поэтому давайте сразу считаем входные данные: Здесь переменная n даже не преобразовывается в числовой тип, потому что мы всё равно не будем её использовать. А из второй строки делаем список целых чисел, потому что нам надо будет их сравнивать, складывать и перемножать. Решим первую часть. Для вычисления суммы списка (и не только) есть замечательная функция sum: sum(iterable[, start]) Как же нам выбрать в списке только положительные числа? Воспользуемся ещё одной функцией - filter, которая на вход получает два параметра: преди

Предлагаю посмотреть, как скучную задачу на циклы можно решить с помощью готовых функций на Python. Читаем условие:

Условие задачи с сайта acmp.ru
Условие задачи с сайта acmp.ru

По сути мы видим здесь две отдельных задачи, у которых лишь общие входные данные. Это накладывает единственное незначительное ограничение, что при решении одной задачи нельзя менять входные данные. Например, если бы мы первую часть решали с помощью сортировки массива и суммы некоторого его суффикса (ведь именно там находились бы положительные числа).

Поэтому давайте сразу считаем входные данные:

Считывание входных данных
Считывание входных данных

Здесь переменная n даже не преобразовывается в числовой тип, потому что мы всё равно не будем её использовать. А из второй строки делаем список целых чисел, потому что нам надо будет их сравнивать, складывать и перемножать.

Решим первую часть. Для вычисления суммы списка (и не только) есть замечательная функция sum:

sum(iterable[, start])

Как же нам выбрать в списке только положительные числа? Воспользуемся ещё одной функцией - filter, которая на вход получает два параметра: предикат (функция, которая принимает один параметр и возвращает true или false) и список (на самом деле - любой объект по которому можно итерироваться). Предикат применяется к каждому элементу списка, и остаются только те элементы, для которых получилось значение true.

filter(function, iterable)

Чтобы не создавать отдельно функцию из одного if'а, я буду использовать lambda-функцию:

Вычисление суммы положительных элементов списка
Вычисление суммы положительных элементов списка

Со второй подзадачей немного сложнее, давайте делать по шагам. Для начала вспомним, что есть функции min и max, которые находят минимальный и максимальный элементы соответственно:

min(iterable, *[, key, default])
max(iterable, *[, key, default])

Однако нам нужны индексы этих элементов. Для этого воспользуемся методом index, который есть у массивов. Этот метод находит минимальный индекс массива, значение которого равно заданному:

array.index(x)

Отлично, скомбинируем:

Нахождение индексов минимального и максимального элементов
Нахождение индексов минимального и максимального элементов

Глядя на второй пример из условия задачи, понимаем, что минимальный элемент может стоять правее, чем максимальный. И если мы запустим цикл (или что-то аналогичное) от минимального до максимального, то ничего не выполнится. Поэтому найдём левую и правую границы подмассива, используя уже знакомые функции min и max, но уже с другими сигнатурами:

min(arg1, arg2, *args[, key])
max(arg1, arg2, *args[, key])
Вычисление границ подмассива
Вычисление границ подмассива

Осталась самая сложная часть. Никакой стандартной функции для произведения нет (иначе пришлось бы делать множество функций для всех других возможных арифметических операций).

Но в библиотеке functools есть замечательная функция reduce:

reduce(function, iterable[, initializer])

Которая принимает функцию двух аргументов, возвращающую их агрегацию, и список. Эта функция применяется к каждому элементу списка, где первым параметром подставляется результат агрегации предыдущего шага. Необязательным параметром в reduce является инициализатор для агрегации. Например reduce с функцией foo для списка [1, 2, 3, 4] развернётся в следующую последовательность:

foo(foo(foo(1, 2), 3), 4)

Кажется, что это то, что нам нужно, если вместо foo сделать функцию произведения элементов подмассива:

Подключение функции из библиотеки
Подключение функции из библиотеки
Произведение элементов подмассива
Произведение элементов подмассива

Такое красивое и лаконичное решение получилось. Особенно советую поэкспериментировать с функцией reduce - она обладает большими возможностями.

Предыдущий выпуск: Задача 527. Алгоритм Евклида

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