Peter Otten wrote: ...... > - You are padding twice -- once with None, and then with the real thing. > > def interleave2(*args, **kw): > dopad = "pad" in kw > pad = kw.get("pad") > count = len(args) > lengths = map(len, args) > maxlen = max(lengths) > if not dopad and min(lengths) != maxlen: > raise ValueError > result = maxlen*count*[pad] > for ix, input in enumerate(args): > result[ix:len(input)*count:count] = input > return result > > $ python -m timeit -s 'from interleave_spencer import xdata, ydata, > interleave as i;xdata=xdata[:-1]' 'i(xdata, ydata, pad=None)' > 10000 loops, best of 3: 69.7 usec per loop > $ python -m timeit -s 'from interleave_spencer import xdata, ydata, > interleave2 as i;xdata=xdata[:-1]' 'i(xdata, ydata, pad=None)' > 10000 loops, best of 3: 46.4 usec per loop > > Not overwhelming, but I expect the difference to grow when the arguments > occupy a significant portion of the available memory. > > Peter very nice indeed; another generalization is to allow truncation as well
def interleave(*args,**kw): """Peter Otten flatten7 (generalized by Michael Spencer and Robin Becker) Interleave any number of sequences, padding shorter sequences if kw pad is supplied or truncating if truncate=True is specified >>> interleave([1,3,5], [2,4,6]) == [1,2,3,4,5,6] True >>> interleave([1,2,3]) == [1,2,3] True >>> interleave(*[[1,2,3]]*10) == [1]*10+[2]*10+[3]*10 True >>> interleave(range(0,1000,2),range(1,1000,2)) == range(1000) True >>> interleave([1,2],[3,4,5]) Traceback (most recent call last): ... ValueError: Minimum length=2 != Max length=3 >>> interleave([1,3],[2,4,6], pad = None) == [1,2,3,4,None,6] True >>> interleave([1,3],[2,4,6],truncate=True) == [1,2,3,4] True >>> interleave([1,2],[3,4,5],pad='aaa',truncate=1) Traceback (most recent call last): ... AssertionError: Cannot specify both truncate=True and pad='aaa' """ dopad = "pad" in kw pad = kw.get("pad") dotrunc = bool(kw.get('truncate',False)) assert not (dotrunc and pad), \ 'Cannot specify both truncate=True and pad=%r' % pad count = len(args) lengths = map(len,args) maxlen = max(lengths) minlen = min(lengths) if dotrunc: result = minlen*count*[None] for ix, input in enumerate(args): result[ix::count] = input[:minlen] else: if not dopad and minlen!=maxlen: raise ValueError('Minimum length=%d != Max length=%d' % (minlen,maxlen)) result = maxlen*count*[pad] for ix, input in enumerate(args): result[ix:len(input)*count:count] = input return result def _test(): import doctest, interleave return doctest.testmod(interleave) if __name__ == "__main__": _test() -- Robin Becker -- http://mail.python.org/mailman/listinfo/python-list