sum for sequences?

Steve Howell showell30 at yahoo.com
Fri Mar 26 10:31:17 EDT 2010


On Mar 24, 4:19 pm, Paul Rubin <no.em... at nospam.invalid> wrote:
> kj <no.em... at please.post> writes:
> > Is there a sequence-oriented equivalent to the sum built-in?  E.g.:
> >   seq_sum(((1, 2), (5, 6))) --> (1, 2) + (5, 6) --> (1, 2, 5, 6)
>
> use itertools.chain for this.  A few people have mentioned that sum will
> also work, but I think for that purpose it could have O(n**2)
> complexity.

I agree on the practical matter that itertools.chain and other
solutions are usually the way to go for most tasks that involve
iterating through several lists.

>From a purely academic standpoint, I'm not convinced that sum() is
inefficient in terms of big-O complexity, though.

 showell at showell-laptop:~$ python
 Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
 [GCC 4.3.3] on linux2
 >>> class StupidList:
 ...   def __init__(self, lst):
 ...     print 'creating', lst
 ...     self.lst = lst
 ...   def __add__(self, other):
 ...     self.lst += '|'
 ...     self.lst.extend(other.lst)
 ...     return self
 ...
 >>> result = sum([StupidList([1, 2]), StupidList([3,4]),
StupidList([5,6])], StupidList([0]))
 creating [1, 2]
 creating [3, 4]
 creating [5, 6]
 creating [0]
 >>> result.lst
 [0, '|', 1, 2, '|', 3, 4, '|', 5, 6]

If I'm interpreting the above program correctly, then sum() is doing
the most efficient thing under the hood--it appears to do the
equivalent of += without creating unnecessary objects for intermediate
sums.

I think the special-case error message might be a case where
practicality simply beats out purity.  It would be nice if sum() were
completely duck-typed-let-you-shoot-yourself-in-foot-if-you-know-what-
you-are-doing, but maybe this was such a pitfall at one time, that
extra safeguards were put into sum().  I wonder how severely sum(),
without the restriction, would underperform join() on modern versions
of Python, though.

 >>> sum('1', '2')
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: sum() can't sum strings [use ''.join(seq) instead]

Note that you can easily fake out sum() to get duck typing.

 >>> class EmptyStringStarter:
 ...   def __add__(self, other): return other
 ...
 >>> empty = EmptyStringStarter()
 >>> sum(['hello ', 'world'], empty)
 'hello world'




More information about the Python-list mailing list