6

I want to "weave" two numberrows together.

Example:

x = [1,2,3]
y = [4,5,6]

result = [1,4,2,5,3,6]

This is my function, I can't find out why it doesn't work:

def weave(list1,list2):
    lijst = []
    i = 0
    for i <= len(list1):
        lijst += [list1[i]] 
        lijst += [list2[i]] 
        i + 1
Weafs.py
  • 22,731
  • 9
  • 56
  • 78
Pieter
  • 141
  • 1
  • 8

8 Answers8

14

You can use the chain function from itertools module to interleave two lists:

x = [1,2,3]
y = [4,5,6]

from itertools import chain
list(chain.from_iterable(zip(x, y)))
# [1, 4, 2, 5, 3, 6]
georg
  • 211,518
  • 52
  • 313
  • 390
Matt
  • 17,290
  • 7
  • 57
  • 71
  • 1
    I would add a strong encouragement to use itertools and similar operations on iterables whenever you are faced with lists of stuff to manipulate in Python. It is far more robust, and far more readable. – Phil H Nov 27 '14 at 09:15
5

Python's for-loops aren't like other languages where you can have a conditional. You need to use a while loop instead or alter your for-loop:

def weave(list1,list2):
    lijst = []
    i = 0
    while i < len(list1):
        lijst.append(list1[i])
        lijst.append(list2[i]) 
        i += 1
    return lijst

I've altered your code in a variety of ways:

  • Use a while loop if you have a condition you want to loop through
  • You want the conditional to be less than the length, not less than or equal to. This is because indexing starts at 0, and if you do <=, then it will try to do list1[3] which is out of bounds.
  • Use list.append to add items to list
  • You forgot the = in i += 1
  • Finally, don't forget to return the list!

You could also use zip():

>>> [a for b in zip(x, y) for a in b]
[1, 4, 2, 5, 3, 6]
TerryA
  • 58,805
  • 11
  • 114
  • 143
3

You can also weave lists by defining the even and odd half-lists of the result list.

x = [1,2,3]
y = [4,5,6]

z = numpy.empty(len(x)+len(y))
z[::2],z[1::2]=x,y

result=z.tolist()
2

You need to append list item at every iteration so use list.append and in python you don't need to initialise i =0.

try this:-

>>> a = [1,2 ,3]
>>> b = [4, 5, 6]
>>> list(chain.from_iterable(zip(a, b)))
[1, 4, 2, 5, 3, 6]
Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
1

You can play with this script:

reduce(lambda a, b: a+b, zip([1, 2, 3], [4, 5, 6]), ())

Notes:

  • zip will make pairs, add will join them;
  • you can use operator.add instead of lambda;
  • itertools.izip can be used if lengths of lists are different.
dmitry_romanov
  • 5,146
  • 1
  • 33
  • 36
1
>>> x = [1,2,3]
>>> y = [4,5,6]
>>> z=[]
>>> for i,j in zip(x,y):
...    z.extend([i,j])
... 
>>> z
[1, 4, 2, 5, 3, 6]
Irshad Bhat
  • 8,479
  • 1
  • 26
  • 36
1

I needed this, but with an arbitrary number of lists of potentially different lengths, which some of the other more elegant answers do not offer. Here is a simple implementation with no dependencies:

def weave_lists(list_of_lists):
    max_index = max([len(sublist) for sublist in list_of_lists])
    weaved_list = []
    for sublist_index in range(max_index):
        for sublist in list_of_lists:
            if len(sublist) > sublist_index:
                weaved_list.append(sublist[sublist_index])
    return weaved_list

print(weave_lists([[1,2], [3,4,5], [6,7,8,9]]))
# [1, 3, 6, 2, 4, 7, 5, 8, 9]
ktolbol
  • 91
  • 1
  • 1
0
x = [1,2,3]
y = [4,5,6]

As mentioned by others (and is the clearest as well as the way I'd do it since it since its the most understandable given the semantics of chain), You can do this by using itertools:

from itertools import chain
list(chain.from_iterable(zip(x, y)))

[1, 4, 2, 5, 3, 6]

However you could also use tuple summing up (concatenation) by:

list(sum(zip(x,y), ()))

[1, 4, 2, 5, 3, 6]

Veltzer Doron
  • 934
  • 2
  • 10
  • 31