I want to merge two lists in python, with the lists being of different lengths, so that the elements of the shorter list are as equally spaced within the final list as possible. i.e. I want to take [1, 2, 3, 4]
and ['a','b']
and merge them to get a list similar to [1, 'a', 2, 3, 'b', 4]
. It needs to be able to function with lists that aren't exact multiples too, so it could take [1, 2, 3, 4, 5]
and ['a', 'b', 'c']
and produce [1, 'a', 2, 'b', 3, 'c', 4, 5]
or similar. It needs to preserve the ordering of both lists.
I can see how to do this by a long-winded brute force method but since Python seems to have a vast array of excellent tools to do all sorts of clever things which I don't know about (yet) I wondered whether there's anything more elegant I can use?
NB: I'm using Python 3.3.
To interleave multiple lists of the same length in Python, we can use list comprehension and zip . We have 3 lists l1 , l2 , and l3 . And then we put them into the lists list. Then to interleave all the lists, we call zip with all the lists in lists as arguments.
Method 3 : Using sum() + zip() + len() Using sum() + zip() , we can get sum of one of the list as summation of 1 if both the index in two lists have equal elements, and then compare that number with size of other list.
Borrowing heavily from Jon Clements' solution, you could write a function that takes an arbitrary number of sequences and returns merged sequence of evenly-spaced items:
import itertools as IT
def evenly_spaced(*iterables):
"""
>>> evenly_spaced(range(10), list('abc'))
[0, 1, 'a', 2, 3, 4, 'b', 5, 6, 7, 'c', 8, 9]
"""
return [item[1] for item in
sorted(IT.chain.from_iterable(
zip(IT.count(start=1.0 / (len(seq) + 1),
step=1.0 / (len(seq) + 1)), seq)
for seq in iterables))]
iterables = [
['X']*2,
range(1, 11),
['a']*3
]
print(evenly_spaced(*iterables))
yields
[1, 2, 'a', 3, 'X', 4, 5, 'a', 6, 7, 'X', 8, 'a', 9, 10]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With