sum for sequences?

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Tue Mar 30 02:41:51 EDT 2010


On Mon, 29 Mar 2010 19:53:04 -0700, Steve Howell wrote:

> On Mar 29, 4:19 pm, Steven D'Aprano <st... at REMOVE-THIS-
> cybersource.com.au> wrote:
[...]
>> Python is under no compulsion to make "the obvious way" obvious to
>> anyone except Guido. It's a bonus if it happens to be obvious to
>> newbies, not a requirement.
>>
>> And besides, what is "it" you're talking about?
>>
>> * Adding integers, decimals or fractions, or floats with a low
>>   requirement for precision and accuracy? Use sum.
>>
>> * Adding floats with a high requirement for precision and accuracy?
>>   Use math.fsum.
>>
>> * Concatenating strings? Use ''.join.
>>
>> * Joining lists? Use [].extend.
>>
>> * Iterating over an arbitrary sequence of arbitrary sequences?
>>   Use itertools.chain.
>>
>> That's five different "its", and five obvious ways to do them.
>>
>>
> Let's go through them...

"Obvious" doesn't mean you don't have to learn the tools you use. It 
doesn't mean that there's no need to think about the requirements of your 
problem. It doesn't even mean that the way to do it has to be a built-in 
or pre-built solution in the standard library, or that somebody with no 
Python experience could intuit the correct function to use based on 
nothing more than a good grasp of English.

It certainly doesn't mean that users shouldn't be expected to know how to 
import a module:


>  >>> fsum([1.234534665989, 2.987, 3])
>  Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
>  NameError: name 'fsum' is not defined

I called it math.fsum every time I referred to it. Did I need to specify 
that you have to import the math module first?


>> * Concatenating strings? Use ''.join.
> 
> 
> Common pitfall:
> 
>  >>> ['abc', 'def', 'ghi'].join()
>  Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
>  AttributeError: 'list' object has no attribute 'join'

Is it really common?

I've been hanging around this newsgroup for many years now, and I don't 
believe I've ever seen anyone confused by this. I've seen plenty of 
newbies use repeated string concatenation, but never anyone trying to do 
a string join and getting it wrong. If you have any links to threads 
showing such confusion, I'd be grateful to see them.


>> * Joining lists? Use [].extend.
> 
> Obvious, yes.  Convenient?  Not really.
> 
>  >>> start = []
>  >>> for list in [[1, 2], [3, 4]]:
>  ...   start.extend(list)
>  ...
>  >>> start
>  [1, 2, 3, 4]


Why isn't that convenient? It is an obvious algorithm written in three 
short lines. If you need a one-liner, write a function and call it:

concatenate_lists(sequence_of_lists)


 
>> * Iterating over an arbitrary sequence of arbitrary sequences?
>>   Use itertools.chain.
> 
>  >>> group1 = ['al', 'bob']
>  >>> group2 = ['cal']
>  >>> groups = [group1, group2]
> 
> Obvious if you are Dutch...

Or are familiar with the itertools module and the Pythonic practice of 
iterating over lazy sequences. Iterators and itertools are fundamental to 
the Pythonic way of doing things.



>  >>> itertools.chain(groups)
>  Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
>  NameError: name 'itertools' is not defined

That's the second time you've either mistakenly neglected to import a 
module, or deliberately not imported it to make the rhetorical point that 
you have to import a module before using it. Yes, you *do* have to import 
modules before using them. What's your point? Not everything has to be a 
built-in.



[...]
> Sum is builtin, but you have to import fsum from math and chain from
> itertools.
>
> Join is actually a method on strings, not sequences.

Is that supposed to be an argument against them?



[...]
> Just commit all that to memory, and enjoy the productivity of using a
> high level language! ;)

If you don't know your tools, you will spend your life hammering screws 
in with the butt of your saw. It will work, for some definition of work. 
Giving saws heavier, stronger handles to make it faster to hammer screws 
is not what I consider good design.



-- 
Steven



More information about the Python-list mailing list