Andrew Channels Dexter Pinion

Wherein I write some stuff that you may like to read. Or not, its up to you really.

October 16, 2003

Sum the squares of a sequence of numbers

There has been a long, long thread on comp.lang.python recently about the joys of lisp. I'm steering well clear of the discussion myself, but one thread-ette caught my attention.

The discussion was how to sum the square of a sequence of numbers. The pseudo code flew fast and furious in both functional and imperative styles. Which prompted a little dabbling, and I came up with this. Given a list of numbers in myList you can calculate the sum of their squares using;

sum([x*x for x in myList])

Posted by Andy Todd at October 16, 2003 10:48 AM

Comments

Nice.

Posted by: Simon Brunning on October 16, 2003 01:23 PM

I didn't read the original thread so I don't know whether this was suggested:

sum(map(lambda x:x*x, myList))

It's really very similar to the list comprehension solution except it uses builtins so, in theory, it should be a bit quicker. However, I don't care about speed (in general), I don't really like lambda much and I prefer a list comprehension to map so I would never actually do it like this ;-).

Posted by: Matt Goodall on October 16, 2003 02:27 PM

Hi. How about this?

from itertools import imap
sum(imap(lambda x: x*x, myList)

This solution does not require the construction of an interim list, as does the other two solutions.

Both sum([x*x for x in myList]) and sum(map(lambda x:x*x, myList)) are equivalent to the following:

squared = []
for x in myList:
    squared.append(x*x)
result = 0
for x in squared:
    result += x

Using imap() instead of map, the equivalent becomes:

result = 0
for x in myList:
    result += x*x

Note that each of these solutions are comparable in speed, however, the imap() solution uses less space, since it never creates a second list. That can be important, for large lists. Still, all things being equal, the sum([x*x for x in myList]) solution wins for readability. If Python had generator comprehensions, the solution would do better with regards to using up space, e.g.

sum([yield x*x for x in myList])

Posted by: Sean Ross on October 17, 2003 12:22 AM