How To Interleave Two Lists Of Different Length?
Solution 1:
This composes a list comprehension using zip_longest
from itertools (which is part of the standard library) to interleave items from both lists into a tuple
, which by default uses None
as the fillvalue.
This also uses chain
also from itertools
to flatten the list.
Finally it filters the None
items from the list:
from itertools import chain, zip_longest
deftwolists(l1, l2):
return [x for x in chain(*zip_longest(l1, l2)) if x isnotNone]
Or as recommended from @EliKorvigo, use itertools.chain.from_iterable
for iterating lazily:
deftwolists(l1, l2):
return [x for x in chain.from_iterable(zip_longest(l1, l2)) if x isnotNone]
Testing
In[56]: twolists([0, 1], ['w', 'x'])
Out[56]: [0, 'w', 1, 'x']In[57]: twolists([0, 1], ['w', 'x', 'y', 'z'])
Out[57]: [0, 'w', 1, 'x', 'y', 'z']In[74]: twolists([0, 1, 2, 3], ['w', 'x'])
Out[74]: [0, 'w', 1, 'x', 2, 3]
Solution 2:
deftwolists(list1, list2):
newlist = []
a1 = len(list1)
a2 = len(list2)
for i inrange(max(a1, a2)):
if i < a1:
newlist.append(list1[i])
if i < a2:
newlist.append(list2[i])
return newlist
Solution 3:
A basic approach:
You could zip()
the lists normally, and append the rest of the biggest list if both lists are not the same size:
deftwo_lists(lst1, lst2):
result = []
for pair inzip(lst1, lst2):
result.extend(pair)
iflen(lst1) != len(lst2):
lsts = [lst1, lst2]
smallest = min(lsts, key = len)
biggest = max(lsts, key = len)
rest = biggest[len(smallest):]
result.extend(rest)
return result
Which works as follows:
>>> print(two_lists([], ['w', 'x', 'y', 'z']))
['w', 'x', 'y', 'z']
>>> print(two_lists([0, 1], ['w', 'x']))
[0, 'w', 1, 'x']
>>> print(two_lists([0, 1], ['w', 'x', 'y', 'z']))
[0, 'w', 1, 'x', 'y', 'z']
>>> print(two_lists([0, 1, 2, 3], ['w', 'x']))
[0, 'w', 1, 'x', 2, 3]
Another possible approach:
You could also use collections.deque
to convert the lists to deque()
objects beforehand, and pop off the beginning of each one with popleft()
, until one of the objects is empty. Then you could append the rest of the list that is not yet empty.
Here is an example:
deftwo_lists2(lst1, lst2):
result = []
fst, snd = deque(lst1), deque(lst2)
while fst and snd:
result.append(fst.popleft())
result.append(snd.popleft())
rest = leftover(fst, snd)
if rest:
result.extend(rest)
return result
defleftover(x, y):
if x andnot y:
return x
elif y andnot x:
return y
returnNone
Note: Both of the approaches are O(n)
time, which is expected for this kind of problem.
Solution 4:
defCombineLists(lst1, lst2):
return [item for x inzip(lst1,lst2) for item in x] + /
(lst2[len(lst1):] iflen(lst2)>len(lst1) else lst1[len(lst2):])
Solution 5:
Here's a solution that deals in iterators. The advantage to this is that it will work with any iterable data structure, not just lists.
deftwolists(list1, list2):
result = []
iter1 = iter(list1)
iter2 = iter(list2)
try:
whileTrue:
result.append(next(iter1))
result.append(next(iter2))
except StopIteration:
# This exception will be raised when either of the iterators# hits the end of the sequence.pass# One of the lists is exhausted, but not both of them. We need# to finish exhausting the lists.try:
whileTrue:
result.append(next(iter1))
except StopIteration:
passtry:
whileTrue:
result.append(next(iter2))
except StopIteration:
passreturn result
Post a Comment for "How To Interleave Two Lists Of Different Length?"