2

I have three lists with elements :

a = [[0,1],[2,3],...]
b = [[5,6],[7,8],...]

c = []

I want to append elements from a and b into c to get:

c = [ [0,1],[5,6],[2,3],[7,8],.... ]
Shivkumar kondi
  • 6,458
  • 9
  • 31
  • 58

7 Answers7

6

Basic approach:

>>> a = [[0,1],[2,3]]
>>> b = [[5,6],[7,8]]
>>> c = []
>>> for pair in zip(a,b):
...   c.extend(pair)
... 
>>> c
[[0, 1], [5, 6], [2, 3], [7, 8]]
>>> 

This breaks if the lengths aren't equal. But you can deal with that case as an exercise.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
5

Another very simple approach using string slicing (and most performance efficient) as:

>>> a = [[0,1],[2,3]]
>>> b = [[5,6],[7,8]]
>>> c = a + b # create a list with size = len(a) + len(b)
>>> c[::2], c[1::2] = a, b  # alternately insert the value
>>> c
[[0, 1], [5, 6], [2, 3], [7, 8]]

Below is the comparison of results with timeit for the answers mentioned here (Python version: 2.7):

  1. Using string slicing: 0.586 usec per loop

    moin@moin-pc:~$ python -m "timeit" -s "a = [[0,1],[2,3]]; b = [[5,6],[7,8]];" "c = a + b; c[::2], c[1::2] = a, b"
    1000000 loops, best of 3: 0.586 usec per loop
    
  2. Using itertools.chain(): 1.89 usec per loop

    moin@moin-pc:~$ python -m "timeit" -s "from itertools import chain; a = [[0,1],[2,3]]; b = [[5,6],[7,8]];" "c = list(chain(*zip(a, b)))"
    1000000 loops, best of 3: 1.89 usec per loop
    
  3. Using reduce(): 0.829 usec per loop

    moin@moin-pc:~$ python -m "timeit" -s "import operator; a = [[0,1],[2,3]]; b = [[5,6],[7,8]];" "c = reduce(operator.concat, zip(a, b))"
    1000000 loops, best of 3: 0.829 usec per loop
    
  4. Using list.extend(): 0.824 usec per loop

     moin@moin-pc:~$ python -m "timeit" -s "a = [[0,1],[2,3]]; b = [[5,6],[7,8]]; c=[]" "for pair in zip(a,b): c.extend(pair)"
     1000000 loops, best of 3: 0.824 usec per loop
    
  5. Using list.append() twice: 1.04 usec per loop

    moin@moin-pc:~$ python -m "timeit" -s "a = [[0,1],[2,3]]; b = [[5,6],[7,8]]; c=[]" "for a_element, b_element in zip(a, b): c.append(a_element); c.append(b_element)"
    1000000 loops, best of 3: 1.04 usec per loop
    
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • Ok. But you really should pass `timeit` those setup statements using the `-s` option. FWIW, in Python 3.6 my `[*chain(*zip(a, b))]` is about 10% faster than my `list(chain...)`version, and my list comp is slightly faster than that. – PM 2Ring Oct 18 '16 at 11:39
  • @PM2Ring: Yes, you are right. I missed that. Updated the answer. – Moinuddin Quadri Oct 18 '16 at 11:47
  • 1
    @PM2Ring: I am using `Python 2.7`, so could not evaluate it for the syntax you mentioned. But I have already mentioned in my answer that my evaluation is for `Python 2.7` – Moinuddin Quadri Oct 18 '16 at 11:52
2

You could zip the two lists and then reduce them to a flat list:

import operator
c = reduce(operator.concat, zip(a, b))
Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

Assuming the two lists are the same length, the most compact way to do this uses itertools.chain and zip.

from itertools import chain

a = [[0,1],[2,3],[10,11],[12,13]]
b = [[5,6],[7,8],[15,16],[17,18]]

c = [*chain(*zip(a, b))]
print(c)

output

[[0, 1], [5, 6], [2, 3], [7, 8], [10, 11], [15, 16], [12, 13], [17, 18]]

As juanpa.arrivillaga mentions in the comments, that syntax will not work on older versions of Python. Instead, you can do

c = list(chain(*zip(a, b)))

Here's another option, which doesn't use imports or the * splat operator:

c = [u for t in zip(a, b) for u in t]

If you need to handle input lists of unequal length, take a look at the roundrobin function in Itertools Recipes. Eg,

c = list(roundrobin(a, b))
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
1

Consider:

merged = []
for a_element, b_element in zip(a, b):
    merged.append(a_element)
    merged.append(b_element)

Unless you have very stringent performance requirements, the simplest approach is the right approach.

Jacob Panikulam
  • 1,196
  • 1
  • 9
  • 12
1

Using more_itertools which implements the itertools roundrobin recipe

>>> from more_itertools import roundrobin
>>> a = [[0,1],[2,3]]
>>> b = [[5,6],[7,8]]
>>> list(roundrobin(a, b))
[[0, 1], [5, 6], [2, 3], [7, 8]]
jamylak
  • 128,818
  • 30
  • 231
  • 230
0

Assuming len(a) == len(b) and you're adding them one by one in turn:

for i in range(len(a)):
        c.append(a[i])
        c.append(b[i])

However, I would recommend to use c = deque(). Since deques are much quicker if you are making a lot of appends.

Nurjan
  • 5,889
  • 5
  • 34
  • 54