Я ищу лучшее/более Pythonic решение для следующего фрагмента
count = sum(1 for e in iterable if e)
Я ищу лучшее/более Pythonic решение для следующего фрагмента
count = sum(1 for e in iterable if e)
len(filter(None, iterable))
Использование None
в качестве предиката для filter
просто говорит об использовании правдоподобия элементов. (возможно, четче было бы len(filter(bool, iterable))
)
Честно говоря, я не могу придумать лучшего способа сделать это, чем то, что у вас есть.
Ну, я думаю, люди могут спорить о "лучше", но я думаю, что вы вряд ли найдете что-нибудь более короткое, более простое и понятное.
Большинство Pythonic должно написать небольшую вспомогательную функцию и поместить ее в ваш надежный модуль "Утилиты" (или подмодуль соответствующего пакета, когда у вас будет достаточно; -):
import itertools as it
def count(iterable):
"""Return number of items in iterable."""
return sum(1 for _ in iterable)
def count_conditional(iterable, predicate=None):
"""Return number of items in iterable that satisfy the predicate."""
return count(it.ifilter(predicate, iterable))
То, как вы решили реализовать эти утилиты, менее важно (вы могли бы в любой момент выбрать некоторые из них в Cython, например, если некоторые профилирования приложения, использующего утилиты, показывают, что это полезно): ключевым моментом является имея их собственную полезную библиотеку функций утилиты с именами и шаблонами вызовов, которые вам нравятся, чтобы сделать ваш код важного кода приложения более понятным, понятным и более кратким, если вы наполнили его полными инкрустациями! -)
sum(not not e for e in iterable)
Это не самый быстрый, но, возможно, удобный для кода-гольфа
sum(map(bool, iterable))
Если вы просто пытаетесь выяснить, не является ли итерабельным, то это, вероятно, поможет:
def is_iterable_empty(it):
try:
iter(it).next()
except StopIteration:
return True
else:
return False
В других ответах будет выполнено время O (N) (и некоторые возьмут память O (N), добрый глаз, Джон!). Эта функция принимает O (1) раз. Если вам действительно нужна длина, другие ответы помогут вам больше.
Упрощенный самый питоновский способ - написать код, который не нуждается в функции count.
Обычно быстрее всего писать стиль функций, с которыми вам больше всего нравится, и продолжать совершенствовать свой стиль.
Записать код, часто читаемый.
Кстати, ваш код не делает то, что говорит ваш заголовок! Для подсчета не 0 элементов не просто рассматривать ошибки округления в плавающих числах, что False - 0..
Если в списке нет значений с плавающей запятой, это может сделать это:
def nonzero(seq):
return (item for item in seq if item!=0)
seq = [None,'', 0, 'a', 3,[0], False]
print seq,'has',len(list(nonzero(seq))),'non-zeroes'
print 'Filter result',len(filter(None, seq))
"""Output:
[None, '', 0, 'a', 3, [0], False] has 5 non-zeroes
Filter result 3
"""
Вот решение с O (n) временем выполнения и O (1) дополнительной памятью:
count = reduce(lambda x,y:x+y, imap(lambda v: v>0, iterable))
Надеюсь, что это поможет!