Ответ 1
Вы можете сделать это с помощью простого одного вкладыша:
l1 = [1, 2, 3, 'A']
sum(filter(lambda i: isinstance(i, int), l1))
# prints 6
Или, если вам нужно это внутри функции:
def foo(l1):
return sum(filter(lambda i: isinstance(i, int), l1))
Кроме того, как отмечено в комментариях, не используйте для своих переменных имена типа dict
и list
; * они будут затенять имена встроенных имен для типов словаря (dict
) и (list
). Затем вам нужно явно указать del dict, list
, чтобы использовать их по назначению.
Но позвольте мне объяснить. Что filter
здесь:
a) В качестве первого аргумента требуется функция:
# this function will return True if i is an int
# and false otherwise
lambda i: isinstance(i, int)
а затем берет каждый элемент внутри списка l1
(второй аргумент) и оценивает, является ли он True
или False
на основе функции.
b). Затем filter
по существу будет отфильтровывать любые объекты внутри списка l1
, которые не являются экземплярами int
(то есть функция возвращает False
для них). В результате для списка, такого как [1, 2, 3, 'A']
, фильтр вернет [1, 2, 3]
, который затем будет суммирован sum()
.
Некоторые примеры:
foo([1, 2, 3, 'A'])
# 6
foo([1, 2, 3])
# 6
foo([1, 2, 3, 'HELLO', 'WORLD'])
# 6
Незначительное предупреждение:
Как и в этом случае, это не суммирует значения float
, оно отбрасывает их (и любые другие числовые типы для этого случая). Если вам это нужно, просто добавьте тип float
в функцию lambda
так:
lambda i: isinstance(i, (int, float))
Теперь ваша сумма сумм тоже плавает:
foo([1, 2, 3, 3.1, 'HELLO', 'WORLD'])
# 9.1
Добавьте любые другие типы, если необходимо, в функцию lambda
, чтобы поймать нужные вам случаи.
Ухватить весь случай:
Как отмечено @Copperfield, вы можете проверить объекты, являющиеся экземплярами любого числа, используя numbers.Number
абстрактный базовый класс в модуле numbers
. Это действует как регистр для числовых значений:
import numbers # must import
sum(filter(lambda i: isinstance(i, numbers.Number), l1))
Упростить и немного быстрее:
Кроме того, как отмечено @ShadowRanger, и поскольку lambda
может быть не самой удобной конструкцией для новых пользователей, можно просто использовать выражение генератора (которое также быстрее) с sum
, чтобы получить тот же точный результат:
sum(val for val in l1 if isinstance(val, numbers.Number))