Может кто-нибудь мне помочь? Я пытаюсь найти способ вычислить
>>> sum_widths = sum(col.width for col in cols if not col.hide)
а также подсчитать количество элементов в этой сумме, не выполняя два прохода над cols
.
Это кажется невероятным, но после сканирования std-lib (встроенные функции, itertools, functools и т.д.) я даже не мог найти функцию, которая учитывала бы количество членов в итерабельном. Я нашел функцию itertools.count
, которая звучит так, как я хочу, но это действительно просто обманчиво названная функция range
.
После небольшой мысли я придумал следующее (что так просто, что отсутствие библиотечной функции может быть оправдано, за исключением его тупости):
>>> visable_col_count = sum(col is col for col in cols if not col.hide)
Однако, используя эти две функции, требуется два прохода итерабельного, что просто портит меня неправильно.
В качестве альтернативы, следующая функция выполняет то, что я хочу:
>>> def count_and_sum(iter):
>>> count = sum = 0
>>> for item in iter:
>>> count += 1
>>> sum += item
>>> return count, sum
Проблема заключается в том, что она занимает в 100 раз больше (согласно timeit
) как сумму формы выражения генератора.
Если кто-нибудь может придумать простой однострочный вкладыш, который делает то, что я хочу, сообщите мне (используя Python 3.3).
Изменить 1
Здесь много замечательных идей, ребята. Спасибо всем, кто ответил. Мне потребуется некоторое время, чтобы переварить все эти ответы, но я сделаю это, и я постараюсь выбрать его для проверки.
Изменить 2
Я повторил тайминги по моим двум скромным предложениям (функция count_and_sum
и две отдельные функции sum
) и обнаружил, что мое первоначальное время было упущено, возможно, из-за процесса автоматического резервного копирования, выполняющегося в фоновом режиме.
Я также приурочил большинство замечательных предложений, приведенных здесь в качестве ответов, все с той же моделью. Анализ этих ответов был для меня довольно учебным: новое использование для deque
, enumerate
и reduce
и первое время для count
и accumulate
. Спасибо всем!
Вот результаты (из моего медленного нетбука) с использованием программного обеспечения, которое я разрабатываю для отображения:
┌───────────────────────────────────────────────────────┐
│ Count and Sum Timing │
├──────────────────────────┬───────────┬────────────────┤
│ Method │Time (usec)│Time (% of base)│
├──────────────────────────┼───────────┼────────────────┤
│count_and_sum (base) │ 7.2│ 100%│
│Two sums │ 7.5│ 104%│
│deque enumerate accumulate│ 7.3│ 101%│
│max enumerate accumulate │ 7.3│ 101%│
│reduce │ 7.4│ 103%│
│count sum │ 7.3│ 101%│
└──────────────────────────┴───────────┴────────────────┘
(Я не успевал сложные и складные методы как слишком неясные, но в любом случае спасибо.)
Поскольку между всеми этими методами очень мало различий во времени, я решил использовать функцию count_and_sum
(с явным циклом for
) как наиболее читаемый, явный и простой (Python Zen), а также Быстрее!
Мне хотелось бы, чтобы один из этих замечательных ответов был правильным, но все они одинаково хороши, хотя более или менее неясными, поэтому я просто все голосую и принимаю свой собственный ответ как правильный (count_and_sum
function), поскольку что я использую.
Что было в том, что "Должен быть один - и желательно только один - простой способ сделать это".