I was recently asked to take two lists and interleave them. Although I can not
think of a scenario off the top of my head where this might be useful, it doesn't
strike me as a completely silly thing to do.
StackOverflow's top answer
for this problem uses itertools.chain.from_iterable()
and itertools.izip()
(which is just the builtin zip()
in Python 3) to do this. This answer runs into
the problem of how to handle variable length arrays. Fortunately, we have
itertools.izip_longest()
(and itertools.zip_longest()
in Python 3) for that!
a = [ 1, 2, 3 ]
b = [ 'a', 'b', 'c', 'd' ]
from itertools import chain, izip_longest
c = list(chain.from_iterable(izip_longest(a, b)))
# [1, 'a', 2, 'b', 3, 'c', None, 'd']
[ x for x in c if x is not None ]
# [1, 'a', 2, 'b', 3, 'c', 'd']
It is important to note here that the default fill value for izip_longest()
is
None
. That creates an item in our array with the None
value. Usually, we could
just use filter()
to return the list with all false values removed, but there
might be a case where our list contains 0, False
, or ''.
To work around that, we use the final list comprehension to remove all the None
values specifically. In the case where we actually want None
values, we would
need to give izip_longest()
a garbage fill value that can not possibly appear
in our dataset and then work from there.