On Fri, 30 Sep 2005 09:38:25 -0700, Michael Spencer <[EMAIL PROTECTED]> wrote: >Terry Reedy wrote: >> "David Murmann" <[EMAIL PROTECTED]> wrote in message >> news:[EMAIL PROTECTED] >> >>>>def join(sep, seq): >>>> return reduce(lambda x, y: x + sep + y, seq, type(sep)()) >>> >>>damn, i wanted too much. Proper implementation: >>> >>>def join(sep, seq): >>> if len(seq): >>> return reduce(lambda x, y: x + sep + y, seq) >>> return type(sep)() >>> >>>but still short enough >> >> >> For general use, this is both too general and not general enough. >> >> If len(seq) exists then seq is probably reiterable, in which case it may be >> possible to determine the output length and preallocate to make the process >> O(n) instead of O(n**2). I believe str.join does this. A user written >> join for lists could also. A tuple function could make a list first and >> then tuple(it) at the end. >> >> If seq is a general (non-empty) iterable, len(seq) may raise an exception >> even though the reduce would work fine. >> >> Terry J. Reedy >> >> >> >For the general iterable case, you could have something like this: > > >>> def interleave(sep, iterable): > ... it = iter(iterable) > ... next = it.next() > ... try: > ... while 1: > ... item = next > ... next = it.next() > ... yield item > ... yield sep > ... except StopIteration: > ... yield item > ... > >>> list(interleave(100,range(10))) > [0, 100, 1, 100, 2, 100, 3, 100, 4, 100, 5, 100, 6, 100, 7, 100, 8, 100, 9] > >>> > >but I can't think of a use for it ;-)
I have this version: def interlace(x, i): """interlace(x, i) -> i0, x, i1, x, ..., x, iN """ i = iter(i) try: yield i.next() except StopIteration: return for e in i: yield x yield e And I use it for things like interleave(", ", ["foo", bar, "baz"]), where bar is not a string, but can be handled along with strings by a lower-level chunk of code. Jp -- http://mail.python.org/mailman/listinfo/python-list