Zipping lists of unequal size
I have two lists
a = [1,2,3]
b = [9,10]
I want to combine (zip) these two lists into one list c
such that
c = [(1,9), (2,10), (3, )]
Is there any function in standard library in Python to do this?
Solution 1:
Normally, you use itertools.zip_longest
for this:
>>> import itertools
>>> a = [1, 2, 3]
>>> b = [9, 10]
>>> for i in itertools.zip_longest(a, b): print(i)
...
(1, 9)
(2, 10)
(3, None)
But zip_longest
pads the shorter iterable with None
s (or whatever value you pass as the fillvalue=
parameter). If that's not what you want then you can use a comprehension to filter out the None
s:
>>> for i in (tuple(p for p in pair if p is not None)
... for pair in itertools.zip_longest(a, b)):
... print(i)
...
(1, 9)
(2, 10)
(3,)
but note that if either of the iterables has None
values, this will filter them out too. If you don't want that, define your own object for fillvalue=
and filter that instead of None
:
sentinel = object()
def zip_longest_no_fill(a, b):
for i in itertools.zip_longest(a, b, fillvalue=sentinel):
yield tuple(x for x in i if x is not sentinel)
list(zip_longest_no_fill(a, b)) # [(1, 9), (2, 10), (3,)]
Solution 2:
Another way is map
:
a = [1, 2, 3]
b = [9, 10]
c = map(None, a, b)
Although that will too contain (3, None)
instead of (3,)
. To do that, here's a fun line:
c = (tuple(y for y in x if y is not None) for x in map(None, a, b))