У меня есть итерация записей, по которым я хотел бы собрать некоторую простую статистику, скажем, счет всех чисел, делимых на два, и счет всех чисел, делимых на три.
Моя первая альтернатива, хотя и повторяющаяся по списку только один раз и избегающая расширения списка (и помня о рефакторинге split *1004*), выглядит довольно раздутой:
(альт 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
Это выглядит довольно красиво, но имеет недостаток, заключающийся в расширении выражения до списка:
(альт 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])
Что мне действительно нужно, так это что-то вроде этой функции:
(альт 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)
и хотя самый маленький (и в моей книге, вероятно, самый элегантный), он не очень хорошо выражает намерение.
Итак, мой вопрос к вам:
Какая альтернатива вам больше нравится для сбора этих типов статистики? Не стесняйтесь предлагать собственную альтернативу, если у вас есть что-то лучше.
Чтобы устранить некоторую путаницу ниже:
- На самом деле мои предикаты фильтра более сложны, чем просто этот простой тест.
- Объекты, которые я перебираю, больше и сложнее, чем просто числа
- Мои функции фильтра более различны и их трудно параметризировать в один предикат