title: Need a fast way to count and sum an iterable in a single pass
body: <p>Can any one help me? I'm trying to come up with a way to compute </p>
  
  <pre><code>&gt;&gt;&gt; sum_widths = sum(col.width for col in cols if not col.hide)
  </code></pre>
  
  <p>and also count the number of items in this sum, without having to make two passes over <code>cols</code>. </p>
  
  <p>It seems unbelievable but after scanning the std-lib (built-in functions, itertools, functools, etc), I couldn't even find a function which would count the number of members in an iterable.  I found the function <code>itertools.count</code>, which sounds like what I want, but It's really just a deceptively named <code>range</code> function. </p>
  
  <p>After a little thought I came up with the following (which is so simple that the lack of a library function may be excusable, except for its obtuseness):</p>
  
  <pre><code>&gt;&gt;&gt; visable_col_count = sum(col is col for col in cols if not col.hide)
  </code></pre>
  
  <p>However, using these two functions requires two passes of the iterable, which just rubs me the wrong way. </p>
  
  <p>As an alternative, the following function does what I want:</p>
  
  <pre><code>&gt;&gt;&gt; def count_and_sum(iter):
  &gt;&gt;&gt;     count = sum = 0
  &gt;&gt;&gt;     for item in iter:
  &gt;&gt;&gt;         count += 1
  &gt;&gt;&gt;         sum += item
  &gt;&gt;&gt;     return count, sum
  </code></pre>
  
  <p>The problem with this is that it takes 100 times as long (according to <code>timeit</code>) as the sum of a generator expression form. </p>
  
  <p>If anybody can come up with a simple one-liner which does what I want, please let me know (using Python 3.3).</p>
  
  <p><strong>Edit 1</strong></p>
  
  <p>Lots of great ideas here, guys. Thanks to all who replied. It will take me a while to digest all these answers, but I will and I will try to pick one to check.</p>
  
  <p><strong>Edit 2</strong></p>
  
  <p>I repeated the timings on my two humble suggestions (<code>count_and_sum</code> function and 2 separate <code>sum</code> functions) and discovered that my original timing was way off, probably due to an auto-scheduled backup process running in the background. </p>
  
  <p>I also timed most of the excellent suggestions given as answers here, all with the same model. Analysing these answers has been quite an education for me: new uses for <code>deque</code>, <code>enumerate</code> and <code>reduce</code> and first time for <code>count</code> and <code>accumulate</code>. Thanks to all!</p>
  
  <p>Here are the results (from my slow netbook) using the software I'm developing for display:</p>
  
  <pre><code>┌───────────────────────────────────────────────────────┐
  │                 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%│
  └──────────────────────────┴───────────┴────────────────┘
  </code></pre>
  
  <p>(I didn't time the complex and fold methods as being just too obscure, but thanks anyway.)</p>
  
  <p>Since there's very little difference in timing among all these methods I decided to use the <code>count_and_sum</code> function (with an explicit <code>for</code> loop) as being the most readable, explicit and simple (Python Zen) and it also happens to be the fastest! </p>
  
  <p>I wish I could accept one of these amazing answers as correct but they are all equally good though more or less obscure, so I'm just up-voting everybody and accepting my own answer as correct (<code>count_and_sum</code> function) since that's what I'm using.</p>
  
  <p>What was that about "There should be one-- and preferably only one --obvious way to do it."?</p>