Сложить целое и None
Как можно складывать, если числа могут быть None? Постоянно проверять через if или есть какой-нибудь другой способ?
Ответы (8 шт):
Да, в любом случае вам придется как то избавляться от None: либо сразу почистить список, либо по мере прохождения списка проверять на тип.
my_list = [1, None, 2, None, 3, None]
countable_values = [value for value in my_list if value]
sum = sum(countable_values) if countable_values else None
или
my_list = [1, None, 2, None, 3, None]
sum = 0
for value in my_list:
if value:
sum += value
Я могу предложить 2 однострочных варианта
my_list = [1, None, 2, None, 3, None, "asdasd", '123123']
# Если нам нужны только числа
new_list = [value for value in my_list if isinstance(value, int)]
print(new_list)
# Если нужно проверить что строка это число
new_list = [ int(value) for value in my_list if isinstance(value, int) or isinstance(value, str) == True and value.isdigit()]
print(new_list)
Да постоянно проверять через if, как указано в дзен питона. Создание альтернативной структуры без None, на мой взгляд не целесообразно, так как при больших размерах влечёт увеличение расхода оперативной памяти. Так же есть вариант использования try-except, но это замедлит выполнение программы.
Есть волшебная функция. в модуле numpy
import numpy as np
a = [None, None, 8, None,6, None, None, 9, None, None, None, 3, None]
print(np.nansum(np.array(a, dtype=float)))
26.0
Дополню комментарий @ganz
import datetime
my_list = [большой массив из int, None, str]
print("Используем итератор")
time_start = datetime.datetime.now()
# Если нужно проверить что строка это число
new_list = [ int(value) for value in my_list if isinstance(value, int) or isinstance(value, str) == True and value.isdigit()]
time_end = datetime.datetime.now()
print(f"Время работы: {time_end - time_start}\nИсходный размер массива: {len(my_list)}\nФинальный размер массива: {len(new_list)}")
print("------------------------------")
print("Используем try-except")
new_list1 = []
time_start1 = datetime.datetime.now()
for i in my_list:
try:
new_list1.append(int(i))
except:
pass
time_end1 = datetime.datetime.now()
print(f"Время работы: {time_end1 - time_start1}\nИсходный размер массива: {len(my_list)}\nФинальный размер массива: {len(new_list1)}")
print("------------------------------")
print("Создание структуры без None")
time_start2 = datetime.datetime.now()
list_not_none = []
for i in my_list:
if i:
list_not_none.append(i)
new_list2 = []
for j in list_not_none:
if isinstance(j, int):
new_list2.append(j)
elif isinstance(j, str):
if j.isdigit():
new_list2.append(int(j))
time_end2 = datetime.datetime.now()
print(f"Время работы: {time_end2 - time_start2}\nИсходный размер массива: {len(my_list)}\nФинальный размер массива: {len(new_list2)}")
Результаты работы:
1 Запуск:
Используем итератор
Время работы: 0:00:00.000997
Исходный размер массива: 14520
Финальный размер массива: 7260
===============================
Используем try-except
Время работы: 0:00:00.005998
Исходный размер массива: 14520
Финальный размер массива: 7260
===============================
Создание структуры без None
Время работы: 0:00:00.003000
Исходный размер массива: 14520
Финальный размер массива: 7260
2 Запуск:
Используем итератор
Время работы: 0:00:00.001004
Исходный размер массива: 14520
Финальный размер массива: 7260
===============================
Используем try-except
Время работы: 0:00:00.005998
Исходный размер массива: 14520
Финальный размер массива: 7260
===============================
Создание структуры без None
Время работы: 0:00:00.003001
Исходный размер массива: 14520
Финальный размер массива: 7260
3 Запуск:
Используем итератор
Время работы: 0:00:00.001999
Исходный размер массива: 14520
Финальный размер массива: 7260
===============================
Используем try-except
Время работы: 0:00:00.006002
Исходный размер массива: 14520
Финальный размер массива: 7260
===============================
Создание структуры без None
Время работы: 0:00:00.004998
Исходный размер массива: 14520
Финальный размер массива: 7260
При этом если создавать новую структуру, мы будем иметь не только массив new_list с размером 59736 байта а еще и создавать временный массив list_not_none с размером в 75672 байта. Оно нам надо?
почему бы не использовать filter:
a = [None, None, 8, None,6, None, None, 9, None, None, None, 3, None]
print(sum(filter(None,a))) # 26
Просто используем map и sum:
a = [4, 4, None, 5]
print(sum(map(lambda x: x or 0, a)))
# 13
Или задействуем reduce:
from functools import reduce
a = [4, 4, None, 5]
print(reduce(lambda x,y: x + (y or 0), a))
# 13
Полно вариантов, но добавлю ещё один короткий, хотя эти идеи по отдельности уже были в других вариантах:
lst = [1, None, 2, 3, 4, None, 6]
print(sum(x or 0 for x in lst))
Данный код заменит значения 0 и None на 0 перед суммированием.