flatten a level one list

Bengt Richter bokr at oz.net
Fri Jan 13 13:40:29 EST 2006


On Fri, 13 Jan 2006 07:48:39 -0800, aleax at mail.comcast.net (Alex Martelli) wrote:

>Nick Craig-Wood <nick at craig-wood.com> wrote:
>   ...
>> I agree with Guido about the special case, but I disagree about the
>> error message.  Not being able to use sum(L,"") reduces the
>> orthogonality of sum for no good reason I could see.
>
I agree.

>Having sum(L,'') work but be O(N squared) would be an "attractive
Are you saying ''.join is O(N squared)? Or that sum would not be
allowed to used the same/equivalent implementation algorithms if it were allowed
to work on strings?

>nuisance" within the meaning of the law; it's bad enough that sum(L,[])
>etc are that way, but at least beginners want to concatenate lists (or
>tuples, arrays, etc) much less often than they want to concatenate
>strings.  sum is meant to work on _numbers_ -- the reason it takes that
If sum is meant to work on _numbers_, why not call it numsum, to suggest
the restriction? ISTM the usual assumption in python is non-restrictive duck typing,
and the expectation would be no more restriction than in reduce(operator.add, L, init_val).

>second optional parameter is essentially to be able to specify the
>``type'' of numbers.  In retrospect it might have been better to have a
>single argument (or interpret multiple ones like min or max do, maybe),
>forcing the starting value to be integer 0.
>
So it was an accident that user types are permitted?

 >>> class C:
 ...     def __getattr__(self, attr): print attr;raise AttributeError
 ...
 >>> sum([C(),C()])
 __coerce__
 __radd__
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for +: 'int' and 'instance'
 >>> sum([C(),C()],C())
 __coerce__
 __add__
 __coerce__
 __radd__
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for +: 'instance' and 'instance'

Yet user subclassing of str does not yield an acceptable user type?

 >>> S = type('S',(str,),{})
 >>> sum(S(i) for i in xrange(5))
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for +: 'int' and 'S'
 >>> sum(S(i) for i in xrange(5), S('start:'))
   File "<stdin>", line 1
 SyntaxError: invalid syntax
 >>> sum((S(i) for i in xrange(5)), S('start:'))
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: sum() can't sum strings [use ''.join(seq) instead]

Although, notice

 >>> class SI(str):
 ...     def __add__(self, other): return SI(str.__add__(self, str(other)))
 ...     __radd__ = __add__
 ...
 >>> sum((SI(i) for i in xrange(5)))
 '001234'

But:
 >>> sum((SI(i) for i in xrange(5)), SI('start:'))
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: sum() can't sum strings [use ''.join(seq) instead]
vs
 >>> reduce(operator.__add__, (SI(i) for i in xrange(5)), SI('start:'))
 'start:01234'


Which seems to boil down to incomplete restrictions on duck typing.
Maybe Guido will want to complete it, but ISTM your original implementation
delegating string addition implementation to ''.join was reasonable.

Regards,
Bengt Richter



More information about the Python-list mailing list