[Python-ideas] Another attempt at a sum() alternative: the concatenation protocol

Steven D'Aprano steve at pearwood.info
Tue Jul 16 15:02:39 CEST 2013


On 16/07/13 16:50, Nick Coghlan wrote:
> I haven't been following the sum() threads fully, but something Ron
> suggested gave me an idea for a concatenation API and protocol. I
> think we may also be able to use a keyword-only argument to solve the
> old string.join vs str.join problem in a more intuitive way.

What is the string.join vs str.join problem?

Are you referring to the fact that in Python 1.5, the string.join() function takes arguments in the opposite order to str.join() method? I'm not sure that's a problem, except in the sense that people has to unlearn one and learn the other.


>      def concat(start, iterable, *, interleave=None):
>          try:
>              build = start.__concat__
>          except AttributeError:
>              result = start
>              if interleave is None:
>                  for x in iterable:
>                      result += x
>              else:
>                  for x in iterable:
>                      result += interleave
>                      result += x
>          else:
>              result = build(iterable, interleave=interleave)

I assume that you missed a "return result" at the end of the function.

I don't understand the purpose of interleave:

py> concat([99], [[1], [2], [3]], interleave=[100, 101])
[99, 100, 101, 1, 100, 101, 2, 100, 101, 3]


I would expect interleave should be a zip-like function with this effect:

interleave([1, 2, 3], [100, 101])
=> [1, 100, 2, 101, 3]

so I don't understand why I might want to use the interleave argument above.

I also wonder why this potentially modifies start in place. I would expect that, like sum(), it should return a new object even if start is mutable.

I dislike that start is a mandatory argument. I should be able to concatenate a bunch of (say) strings, or lists, without necessarily supplying a start value. E.g. I can do this with reduce:

py> from functools import reduce
py> from operator import add
py> reduce(add, [[1], [2], [3]])
[1, 2, 3]


That I can't do so with sum() is another reason why sum() is not a well-designed API for strings and lists.


But apart from those criticisms, I like the general idea.



> A simple "use sum for numbers, concat for containers" approach is
> simpler and clearer than trying to coerce sum into being fast for both
> when its assumptions are thoroughly grounded in manipulating numbers
> rather than containers.

+1



-- 
Steven


More information about the Python-ideas mailing list