Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fatest way to mix two lists in python

Tags:

python

list

Let's have 2 lists

l1 = [1, 2, 3]
l2 = [a, b, c, d, e, f, g...]

result:

list = [1, a, 2, b, 3, c, d, e, f, g...] 

Cannot use zip() because it shorten result to the smallest list. I need also a list at the output not an iterable.

like image 439
kollo Avatar asked Sep 29 '12 01:09

kollo


People also ask

How do you combine two lists in Python?

In python, we can use the + operator to merge the contents of two lists into a new list. For example, We can use + operator to merge two lists i.e. It returned a new concatenated lists, which contains the contents of both list_1 and list_2.

How do you combine lists within a list Python?

Concatenate Two Lists in Python In almost all simple situations, using list1 + list2 is the way you want to concatenate lists.


Video Answer


3 Answers

>>> l1 = [1,2,3]
>>> l2 = ['a','b','c','d','e','f','g']
>>> [i for i in itertools.chain(*itertools.izip_longest(l1,l2)) if i is not None]
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']

To allow None values to be included in the lists you can use the following modification:

>>> from itertools import chain, izip_longest
>>> l1 = [1, None, 2, 3]
>>> l2 = ['a','b','c','d','e','f','g']
>>> sentinel = object()
>>> [i
     for i in chain(*izip_longest(l1, l2, fillvalue=sentinel))
     if i is not sentinel]
[1, 'a', None, 'b', 2, 'c', 3, 'd', 'e', 'f', 'g']
like image 153
inspectorG4dget Avatar answered Oct 19 '22 12:10

inspectorG4dget


Another possibility...

[y for x in izip_longest(l1, l2) for y in x if y is not None]

(after importing izip_longest from itertools, of course)

like image 20
Ray Toal Avatar answered Oct 19 '22 12:10

Ray Toal


The simplest way to do this is to use the round robin recipie given in the itertools docs:

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

Which can be used like so:

>>> l1 = [1,2,3]
>>> l2 = ["a", "b", "c", "d", "e", "f", "g"]
>>> list(roundrobin(l1, l2))
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']

Note that 2.x requires a slightly different version of roundrobin, provided in the 2.x docs.

This also avoids the problem the zip_longest() method has in that the lists can contain None without it being stripped out.

like image 2
Gareth Latty Avatar answered Oct 19 '22 13:10

Gareth Latty