У меня есть итерабельность записей, на которых я хотел бы собрать некоторую простую статистику, скажем, подсчет всех чисел, делящихся на два, и количество всех чисел, делящихся на три.
Моя первая альтернатива. Пока только повторяя один раз в списке и избегая расширения списка (и сохраняя рефакторинг split loop), выглядит довольно раздутый:
(alt 1)
r = xrange(1, 10)
twos = 0
threes = 0
for v in r:
if v % 2 == 0:
twos+=1
if v % 3 == 0:
threes+=1
print twos
print threes
Это выглядит довольно неплохо, но имеет недостаток в расширении выражения в списке:
(alt 2)
r = xrange(1, 10)
print len([1 for v in r if v % 2 == 0])
print len([1 for v in r if v % 3 == 0])
Мне бы очень понравилась функция вроде:
(alt 3)
def count(iterable):
n = 0
for i in iterable:
n += 1
return n
r = xrange(1, 10)
print count(1 for v in r if v % 2 == 0)
print count(1 for v in r if v % 3 == 0)
Но это очень похоже на то, что можно было бы сделать без функции. Окончательный вариант:
(alt 4)
r = xrange(1, 10)
print sum(1 for v in r if v % 2 == 0)
print sum(1 for v in r if v % 3 == 0)
и хотя самый маленький (и в моей книге, вероятно, самый элегантный), он не чувствует, что он очень хорошо выражает намерение.
Итак, мой вопрос к вам:
Какую альтернативу вам больше всего нравится собирать эти типы статистики? Не стесняйтесь предоставлять свою собственную альтернативу, если у вас есть что-то лучше.
Чтобы устранить некоторую путаницу ниже:
- В действительности мои предикаты фильтра более сложны, чем просто этот простой тест.
- Объекты, которые я повторяю, больше и сложнее, чем просто числа
- Мои функции фильтра более разные и трудно параметризуются в один предикат