This recipe splices any number of nonempty lists as one list. Each input list may be of different length. Elements of shorter lists may be recycled when the keyword argument recycle is set to True. Any error result in an empty output list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | def splice(alists, recycle = True):
"""
Accepts a list of nonempty lists or indexable objects in
argument alists (each element list may not be of the same
length) and a keyword argument recycle which
if true will reuse elements in lists of shorter length.
Any error will result in an empty list to be returned.
"""
try:
nlists = len(alists)
lens = [len(alist) for alist in alists]
if not recycle:
totlen = sum(lens)
else:
totlen = max(lens) * nlists
pos = [0] * nlists
R = [None] * totlen
i, j = 0, 0
while i < totlen:
if pos[j] < lens[j]:
R[i] = alists[j][pos[j]]
i += 1
pos[j] = pos[j] + 1
if recycle and pos[j] >= lens[j]:
pos[j] = 0
j = (j + 1) % nlists
return R
except:
return []
if __name__ == "__main__":
print splice([[1,2,3], ['a','b'], [4], [-1,-2,-3,-4]], recycle = False)
print splice([[1,2,3], ['a','b'], [4], [-1,-2,-3,-4]])
|
Splicing of two lists of same length without using explicit looping were discussed in comp.lang.python message threads 2006-05-07 00:28:44. This recipe generalizes splicing to more than two lists which may be of different lengths.
Compare with the roundrobin() recipe in the docs for collections module. See: http://www.python.org/doc/current/lib/deque-recipes.html