I am trying to write a Python function that takes two lists as arguments and interleaves them. The order of the component lists should be preserved. If the lists do not have the same length, the elements of the longer list should end up at the end of the resulting list. For example, I'd like to put this in Shell:
interleave(["a", "b"], [1, 2, 3, 4])
And get this back:
["a", 1, "b", 2, 3, 4]
If you can help me I'd appreciate it.
Here's how I'd do it, using various bits of the itertools
module. It works for any number of iterables, not just two:
from itertools import chain, izip_longest # or zip_longest in Python 3
def interleave(*iterables):
sentinel = object()
z = izip_longest(*iterables, fillvalue = sentinel)
c = chain.from_iterable(z)
f = filter(lambda x: x is not sentinel, c)
return list(f)
You could try this:
In [30]: from itertools import izip_longest
In [31]: l = ['a', 'b']
In [32]: l2 = [1, 2, 3, 4]
In [33]: [item for slist in izip_longest(l, l2) for item in slist if item is not None]
Out[33]: ['a', 1, 'b', 2, 3, 4]
izip_longest
'zips' the two lists together, but instead of stopping at the length of the shortest list, it continues until the longest one is exhausted:
In [36]: list(izip_longest(l, l2))
Out[36]: [('a', 1), ('b', 2), (None, 3), (None, 4)]
You then add items by iterating through each item in each pair in the zipped list, omitting those that have a value of None
. As pointed out by @Blckknight, this will not function properly if your original lists have None
values already. If that is possible in your situation, you can use the fillvalue
property of izip_longest
to fill with something other than None
(as @Blckknight does in his answer).
Here is the above example as a function:
In [37]: def interleave(*iterables):
....: return [item for slist in izip_longest(*iterables) for item in slist if item is not None]
....:
In [38]: interleave(l, l2)
Out[38]: ['a', 1, 'b', 2, 3, 4]
In [39]: interleave(l, l2, [44, 56, 77])
Out[39]: ['a', 1, 44, 'b', 2, 56, 3, 77, 4]
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