Hello Alex, On Sun, Oct 26, 2003 at 07:20:52PM +0100, Alex Martelli wrote: > > def sum(seq, start=0): > > for item in seq: > > start = start + seq > > return start > > It IS equivalent to that -- plus an explicit typetest to raise if start is an > instance of str or unicode. Yes, it is what I'm saying: it is what we expect it to be, but there is an exception for no real reason apart from "don't do it like this, buddy, there is a faster version out there". I tend to regard this kind of exceptions as very bad, because if you write a generic algorithm using sum(), even if you don't really see why someone would think about using your algorithm with strings one day, chances are that someone will. Raising a Warning instead of an exception would have had the same result without the generality problem. > > reduce(operator.add, seq, start) > > sum doesn't reproduce reduce's quirk of using the first item of seq if start > is not given. So, the def version is closer. I was thinking about: def sum(seq, start=0): return reduce(operator.add, seq, start) which is the same as the previous one. > Admittedly the latter version may accept a few more cases, e.g. > both versions would accept: > sum([ range(3), 'foo' ], []) > because [] is copyable, []+range(3) is fine, and list.__iadd__ is > more permissive than list.__add__; however, the first version > would fail on: > sum([ 'foo', range(3) ], []) > because []+'foo' fails, while the second version would be fine > because [] is _still_ copyable and __iadd__ is still permissive:-). These cases all show that we have a surprize problem (although probably not a big one). The user will expect sum() to have a clean definition, and because the += one doesn't work, it must be +. To my opinion, sum() should be strictly equivalent to the naive + version and try to optimize common cases under the hood. Admittedly, this is not obvious, because of precisely all these strange mixed type cases which could be user-defined classes with __add__ or __radd__ operators... I'm sure someone will design a class class x: def __add__(self, other): return other so that x() can be used as a trivial starting point for sum() -- and then sum(["abc", "def"], x()) works :-) Armin
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4