flatten a level one list
Robin Becker
robin at reportlab.com
Fri Jan 13 05:55:51 EST 2006
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
More information about the Python-list
mailing list