Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic way to combine two lists in an alternating fashion?

Tags:

python

I have two lists, the first of which is guaranteed to contain exactly one more item than the second. I would like to know the most Pythonic way to create a new list whose even-index values come from the first list and whose odd-index values come from the second list.

# example inputs list1 = ['f', 'o', 'o'] list2 = ['hello', 'world']  # desired output ['f', 'hello', 'o', 'world', 'o'] 

This works, but isn't pretty:

list3 = [] while True:     try:         list3.append(list1.pop(0))         list3.append(list2.pop(0))     except IndexError:         break 

How else can this be achieved? What's the most Pythonic approach?

like image 288
davidchambers Avatar asked Sep 09 '10 17:09

davidchambers


2 Answers

Here's one way to do it by slicing:

>>> list1 = ['f', 'o', 'o'] >>> list2 = ['hello', 'world'] >>> result = [None]*(len(list1)+len(list2)) >>> result[::2] = list1 >>> result[1::2] = list2 >>> result ['f', 'hello', 'o', 'world', 'o'] 
like image 128
Duncan Avatar answered Nov 15 '22 17:11

Duncan


There's a recipe for this in the itertools documentation:

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)) 

EDIT:

For python's version greater than 3:

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)) 
like image 34
David Z Avatar answered Nov 15 '22 16:11

David Z