Я ищу лучше/больше решение Pythonic для следующего отрывка
count = sum(1 for e in iterable if e)
len(filter(None, iterable))
Использование None
в качестве предиката для filter
просто говорит об использовании истинности элементов. (возможно, более ясным было бы len(filter(bool, iterable))
)
Вероятно, самый питонический способ - это написать код, которому не нужна функция 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
"""
Честно говоря, я не могу придумать лучшего способа сделать это, чем то, что есть у вас.
Что ж, я думаю, люди могут спорить о «лучшем», но я думаю, что вы вряд ли найдете что-то короче, проще и яснее.
Это не самый быстрый, но может быть удобно для code-golf
sum(map(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, например, если какое-то профилирование приложения с использованием утилит показывает, что это полезно): главное, чтобы они были вашей собственной полезной библиотекой служебных функций, с именами и шаблонами вызова , которые вам нравятся, чтобы сделать ваш важнейший код уровня более понятным, читабельным и кратким, что если бы вы наполнили его встроенными искажениями ! -)
Если вы просто пытаетесь проверить, не пуст ли итерация, то это, вероятно, поможет:
def is_iterable_empty(it):
try:
iter(it).next()
except StopIteration:
return True
else:
return False
На выполнение других ответов потребуется O (N) времени (а некоторые О (N) память; добрый глаз, Джон!). Эта функция занимает O (1) раз. Если вам действительно нужна длина, другие ответы помогут вам больше.