Given two lists, I want to merge them so that all elements from the first list are even-indexed (preserving their order) and all elements from second list are odd-indexed (a
Use the roundrobin
recipe from itertools:
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
>>> list(roundrobin(x,y))
[0, 3, 1, 4, 2]
This is simple enough although not nearly as flexible as roundrobin
:
def paired(it1, it2):
it2 = iter(it2)
for item in it1:
yield item
yield next(it2)
tested in 2.7.5:
>>> x = [0, 1, 2]
>>> y = [3, 4]
>>> print list(paired(x, y))
[0, 3, 1, 4, 2]
Note that it stops as soon as the list y
runs out (because next(it2)
raises StopIteration).
Here's something you can use. (Use list(izip_longest(...))
for Py2x)
>>> from itertools import chain
>>> from itertools import zip_longest
>>> list(filter(lambda x: x != '', chain.from_iterable(zip_longest(x, y, fillvalue = ''))))
[0, 3, 1, 4, 2]
This works for arbitrary length lists like follows -
>>> x = [0, 1, 2, 3, 4]
>>> y = [5, 6]
>>> list(filter(lambda x: x != '', chain.from_iterable(zip_longest(x, y, fillvalue = ''))))
[0, 5, 1, 6, 2, 3, 4]
Explanation on it's working -
zip_longest(...)
with a fill value zips the lists and fills in the given fill value for iterables of unequal length. So, for your original example, it evaluates to something like [(0, 3), (1, 4), (2, '')]
chain.from_iterable(...)
giving us something like [0, 3, 1, 4, 2, '']
.filter(...)
to remove all occurences of ''
and we get the required answer.It can be done with slicing. Do count
and slice
in terminal:
>>> list1=['Apple','Mango','Orange']
>>> list2=['One','Two','Three']
>>> list = [None]*(len(list1)+len(list2))
>>> list[::2] = list1
>>> list[1::2] = list2
>>> list
Output:
['Apple', 'One', 'Mango', 'Two', 'Orange', 'Three']
You can simply do:
for i,v in enumerate(y):
x.insert(2*i+1,v)
this takes the advantage that insert will use the last index when it is overpassed.
One example:
x = [0,1,2,3,4,5]
y = [100, 11,22,33,44,55,66,77]
print x
# [0, 100, 1, 11, 2, 22, 3, 33, 4, 44, 5, 55, 66, 77]
Try this:
x = [0,1,2,10,11]
y = [3,4]
n = 2*max([len(x),len(y)])
res = n *[None]
res[:2*len(x):2] = x
res[1:2*len(y):2] = y
res = [x for x in res if x!=None]
print res
It should work for unevenly long lists.