Вычисление суммы списка чисел¶
Начнём наше исследование с простой задачи, решение для которой вы уже знаете и без использования рекурсии. Предположим, вы хотите подсчитать сумму списка чисел \([1, 3, 5, 7, 9]\) . Решение в виде итеративной функции показано в ActiveCode 1. Она использует переменную theSum в качестве аккумулятора, чьё начальное значение равно нулю и к которому прибавляются все числа из списка.
Run Save Load Show in Codelens
Итеративное суммирование (lst_itsum)
Представьте на минуту, что вы не можете использовать циклы while или for . Как подсчитать сумму чисел в списке? Если бы вы были математиками, то могли бы начать с того, что сложение — это функция, которая принимает два параметра (пару чисел). Чтобы переопределить задачу от сложения значений в списке к сложению пар чисел, мы перепишем список в виде выражения с полной расстановкой скобок. Выглядеть оно будет примерно так:
\[((((1 + 3) + 5) + 7) + 9)\]
В принципе, скобки можно расставить и в обратном порядке:
\[(1 + (3 + (5 + (7 + 9))))\]
Обратите внимание, что самое внутренне выражение в скобках — \((7 + 9)\) — это задача, которую можно решить без использования циклов или каких-то специальных конструкций. Фактически, мы можем использовать следующую последовательность упрощений для вычисления итоговой суммы:
\[\begin
Осталось только переписать эту идею в виде программы на Python. Для начала, давайте заново сформулируем задачу сложения в терминах списков Python. Мы можем сказать, что что сумма списка numList — это сумма первого его элемента ( numList[0] ) и уже посчитанной суммы остатка списка ( numList[1:] ). В виде функции это выглядит так:
\[ listSum(numList) = first(numList) + listSum(rest(numList)) \label
В этом выражении \(first(numList)\) возвращает первый элемент списка, а \(rest(numList)\) — список из оставшихся чисел. Это легко выражается в коде (см. ActiveCode 2):
Run Save Load Show in Codelens
Рекурсивное суммирование (lst_recsum)
Из этого листинга можно извлечь несколько ключевых моментов. Во-первых, в строке 2 мы проверяем, не является ли список единичным. Эта проверка имеет решающее значение и является “лазейкой” из функции. Нахождение суммы единичного списка — тривиальная задача. Ею будет значение единственного его элемента. Во-вторых, в строке 5 функция вызывает саму себя! Вот почему мы называем алгоритм listsum рекурсивным. Рекурсивная функция — это функция, вызывающая саму себя.
На рисунке 1 показана последовательность рекурсивных вызовов, которые требуются для подсчёта суммы списка \([1, 3, 5, 7, 9]\) . Вы можете думать о ней, как о серии упрощений. Каждый раз, когда мы делаем рекурсивный вызов, мы решаем задачу меньшего размера до тех пор пока не достигнем точки, в которой её нельзя будет уменьшить.
Рисунок 1: Последовательность рекурсивных вызовов для сложения списка чисел.
Когда мы достигаем точки максимального упрощения задачи, то начинаем собирать вместе кусочки решения каждой из маленьких подзадач до тех пор, пока они не сольются в решение первоначальной задачи. Рисунок 2 показывает операции сложения, которые выполняются во время работы listsum в обратном направлении по последовательности вызовов. Когда listsum вернёт ответ самой верхней задачи, мы будем иметь итоговое решение.
Рисунок 2: Последовательность рекурсивных возвратов для сложения списка чисел.
readers online now | | Back to top
© Copyright 2014 Brad Miller, David Ranum. Created using Sphinx 1.2.3.
Как сложить элементы двух списков?
Если важно сохранить начальные списки, то попробуем по другому:
# заполнение переменных a = [1, 2, 3, 4] b = [1, 2, 3] # обработка c = map(sum, zip(a + [0,]*(len(b)-len(a)), b + [0,]*(len(a)-len(b)))) # вывод результата print(list(c))
Вариант 3:
В Python 3.8 появился «морж» — оператор := Если важно не повторить функционал:
# заполнение переменных a = [1, 2, 3, 4] b = [1, 2, 3] # обработка c = map(sum, zip(a + [0, ] * (x := len(b) - len(a)), b + [0, ] * -x)) # вывод результата print(list(c)) Результат: > [2, 4, 6, 4]
Отслеживать
ответ дан 19 мар 2021 в 13:02
121 6 6 бронзовых знаков
Вариант забавный, но 1) он меняет исходные списки, 2) повторяет функционал itertools.zip_longest
19 мар 2021 в 13:10
Так то пусть будет, разные ответы это хорошо )
19 мар 2021 в 13:19
согласен, не без недостатков, но как вариант для «по быстрому»
19 мар 2021 в 13:20
добавил варианты без изменения исходных списков и вариант для Python 3.8 без повтора функционала
19 мар 2021 в 13:54
Если вы еще не «прошли ‘from’ ‘import'», то наиболее простой вариант выглядит вот так:
с=list(map(lambda x, y: x + y, a, b))
c1 = [x+y for x,y in zip(a,b)] + (a if len(a) >= len(b) else b)[min(len(a), len(b)):]
При необходимости обернуть это в вызов функции, надеюсь, сможете сделать самостоятельно: на вход a и b, указанные выражения — в качестве параметра в return.
Отслеживать
ответ дан 22 дек 2019 в 14:14
11.6k 2 2 золотых знака 10 10 серебряных знаков 16 16 бронзовых знаков
Спасибо тебе за ответ) мне нужно просто без комприхенш`на может просто через def и внутри def через for буду рад если поможете = )
23 дек 2019 в 8:51
Если у вас списка ВСЕГДА точно будут одной длины, то можно воспользоваться генератор списков и zip:
a = [1, 2, 3] b = [4, 5, 6] c = [x+y for x, y in zip(a, b)] print(c) #[5, 7, 9]
Но если вы НЕ уверены, что длина списков будет одинаковой хоть раз, то здесь нужно воспользоваться крутой библиотекой itertools:
from itertools import zip_longest a = [1, 2, 3] b = [4, 5, 6, 10] c = [x+y for x, y in zip_longest(a, b, fillvalue=0) #fillvalue нужен, если ваши списки разных рамеров и там где не достаёт элементов, добьёт нулями. print(c) #[5, 7, 9, 10]
Ответ на комментарий:
from itertools import zip_longest def add_list(a, b): c = [x+y for x, y in zip_longest(a, b, fillvalue=0)] return c a = [1, 2, 3] b = [4, 5, 6, 10] summ_list = add_list(a, b) print(summ_list)
Суммировать числа в списке
Суммировать числа в списке можно через функцию sum() .
chars = [1,2,3,4,5] sum(chars) # 15
Обновлено: 01 ноября 2020 | История изменений
Комментарии
Авторизуйтесь, чтобы добавлять комментарии
- Список, кортеж
- Добавить элемент в список
- Удалить элемент в списке
- Размер списка и кортежа
- Суммировать числа в списке
- Сколько раз встречается элемент в списке
- Применить функцию к каждому элементу массива
- Сортировать список
- Разбить текст на список
- Минимальное и максимальное значение элемента списка или кортежа
Сложить элементы из всех списков внутри списка (быстро)
Здравствуйте! Мне нужно очень быстро сложить все элементы из списков внутри списка, процесс выглядит так:
[[[1,2], [3,4,5], [6]], [[7,8], [9], [10]]] —> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
может у библиотеки numpy что-то есть?
Вот мой текущий код:
1 2 3 4 5 6
def sum_list(list_of_lists): return_lst = [] for i in list_of_lists: for i2 in i: return_lst = return_lst + i2 return return_lst
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Заданы несколько списков. Удалить из первого списка все элементы остальных списков
Всем привет, дали такое задание, воспользовался некоторыми кодами в этом форуме, только они не.
условия из двух списков внутри третьего списка
Имеется два списка, необходимо создать третий список из первых двух. Если значения из второго.
Заданы три списка. Удалить из первого списка все элементы остальных списков
Помогите пожалуйста, мне нужно сессию досрочно сдать( в роддом надо) а практика только началась, а.
Суммы всех одномерных списков внутри двумерного
Написать функцию sums2d(lst2d: list), которая из двумерного списка будет выдавать одномерный.
Как сложить сумму из чисел сотен списков и узнать количество списков?
Доброго времени суток! Не могу понять как сложить сумму из несколько тысяч списков. Подскажите.
36829 / 19877 / 4166
Регистрация: 12.02.2012
Сообщений: 33,013
Записей в блоге: 13
Only User, тебе на самом деле нужно линеаризовать сложный список (а не сложить его элементы — если складывать, ответ будет — число 55 )
1 2 3 4 5 6 7 8 9
def linearize(lst): if len(lst)==0: return [] elif type(lst[0]) is list: return linearize(lst[0])+linearize(lst[1:]) else: return [lst[0]]+linearize(lst[1:]) print(linearize([[[1,2], [3,4,5], [6]], [[7,8], [9], [10]]]))
Сообщение от Only User