Pythonic way to sum n-th list element?
Alex Martelli
aleax at aleax.it
Mon Apr 21 12:02:27 EDT 2003
Steve Holden wrote:
...
>> Interesting... I have my doubts on whether Guido would
>> accept such a patch just a week before a beta, but maybe
>> I should try submitting it anyway...
>
> Only one way to resolve those doubts.
Yup -- proof of the pudding, and all that. So, I submitted it and
Guido accepted it for 2.3, EXCEPT...:
> The use of sum() to concatenate a list (please, not a tuple!) of strings
> in such a deterministic way is a masterstroke. It would surely deserve to
> become immediately idiomatic.
...that sum(manystrings) was rejected -- now, when called with any
sequence of strings, sum will raise a TypeError, and remind the user
to use ''.join instead. Not sure why you wanted sum to differentiate
between its argument being a list or tuple when all similar built-ins
these days accept any iterable, but anyway the problem that led to
this came when the argument is an *iterator* -- sum had to jump through
weird hoops to guarantee correct behavior on an iterator (particularly
one freely mixing unicode and non-unicode strings), leading to a factor
of two slowdown with respect to ''.join, and still couldn't ensure the
same semantics as a loop with += in sufficiently weird cases such as:
class Gotcha:
def __add__(self, *whatever): return 23
weirdlist = [ 'xx', Gotcha() ]
print sum(weirdlist)
This _should_ have printed 23, just like reduce(operator.add,weirdlist)
does -- however, due to the string special-case, it ended up delegating
to ''join and thereby raising a TypeError instead. All in all, it did
make much more sense to forbid the first item from being a string (so
as to avoid the performance trap of strings-concatenation done by +).
Interestingly, and characteristically, Tim Peters had expressed strong
instinctive dislike to sum being applicable to (and indeed special-case
optimized for) sequences of strings, even before we had unearthed these
weird examples making the prohibition well-nigh inevitable. timbot
argued that "sum is about numbers" -- and soon he was proved right.
As a bonus -- sum([]) now returns 0, while in my original design it
raised a ValueError, just like e.g. max([]) does. I thought raising an
error was best in the name of "errors shouldn't pass silently" and "in
the face of ambiguity, refuse the temptation to guess". But -- once
we decree that "sum is about numbers", there's no real ambiguity, so we
can have the little extra handiness of having sum([]) not be an error;-).
Alex
More information about the Python-list
mailing list