listcomprehension, add elements?

Maric Michaud maric at aristote.info
Mon Jun 23 08:40:57 EDT 2008


Le Monday 23 June 2008 13:51:34 John Machin, vous avez écrit :
> On Jun 23, 9:16 pm, Maric Michaud <ma... at aristote.info> wrote:
> > Le Monday 23 June 2008 11:39:44 Boris Borcic, vous avez écrit :
> > > John Machin wrote:
> > > > Instead of sum(a + b for a, b in zip(foo, bar))
> > > > why not use sum(foo) + sum(bar)
> > > > ?
> > >
> > > or even sum(foo+bar) as may apply.
> >
> > Because some are better than others :
> >
> > sum(foo+bar) is the worst, it create a superfluous list of len(foo) +
> > len(bar) elements.
> >
> > sum(a + b for a, b in zip(foo, bar)), creates a list of max(len(foo),
> > len(bar)) elements, in most cases it is the same as the former.
> >
> > This could have been corrected using itertools.izip.
> >
> > So the winner is sum(foo) + sum(bar), which does not create anything not
> > needed.
> >
> > But if the question is "how to build the list and sum up all elements in
> > a efficient way for sequences of arbitrary length ", it's important to
> > make it in the same iteration, so the most effective/clear, and so
> > "pythonic", way to do this is (untested) :
> >
> > res, sum = [], 0
>
> Please use tot or total, not sum!
>
> > for s in (a + b for a, b
> >                         in zip(itertools.izip(xrange(1, 51),
>
> Perhaps you should not have left zip() in there ...
>
> >                                                      xrange(50, 0,
> > -1)))): sum += s
> >     res.append(sum)
>
> Do you mean res.append(s) ?
>

Yes, my mistakes, all remarks are indeed true. Sorry for this out of thoughts 
sketch.

> I would have thought that it would have been better to create the list
> and then sum it:
> res = [a + b for a, b in itertools.izip(foo_iter, bar_iter)]
> total = sum(res)
>

This is good enough if you accept the overhead of iterating twice over the 
whole list.

But this may be a bit more complicated, for efficiency, there is a better way 
of allocating memory than successively appending new item.

I guess this should be a far better solution, but you'll need to know the 
required number of iteration (the size of your iterators, the xrange in this 
sample) :

res, total = [None] * n, 0
for i, s in enumerate(a + b for a, b 
                                           in izip(xrange(1, n+1),
                                                     xrange(n, 0, -1)):
    total += s
    res[i] =s

-- 
_____________

Maric Michaud



More information about the Python-list mailing list