3

There should be a way to turn a lists like this:

a = [[1], [2], [3], [4], [5]]
b = [[6], [7], [8], [9], [10]]

to something like this:

c = [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

Right now I'm accomplishing this using for loops.

c = []
for pos in range(len(a)):
    c.append([a[pos], b[pos]])

Anyway for loops are slow and, not to sound like an infomercial but, there has got to be a better way!

2 Answers 2

7

One way is to use column_stack:

>>> np.column_stack((a, b))
array([[ 1,  6],
       [ 2,  7],
       [ 3,  8],
       [ 4,  9],
       [ 5, 10]])

column_stack coerces the lists to arrays first and returns an array.

Since a and b are both a list of lists of a single element, each becomes a 2D column vector when coerced to an array. Because of this fact, you could also use hstack or concatenate to achieve the same thing (they also coerce the lists to arrays that have the correct shape for what we want). Use np.hstack((a, b)) or np.concatenate((a, b), axis=1).

For completeness, it's also possible to use np.c_ by writing np.c_[a, b]. The other methods are more direct and possibly faster though.

Sign up to request clarification or add additional context in comments.

Comments

2

A non-numpy solution is

In [10]: zip(a,b)
Out[10]: [([1], [6]), ([2], [7]), ([3], [8]), ([4], [9]), ([5], [10])]

Oops - not quite. Without the inner brackets, zip does a nice job of regrouping lists:

In [11]: zip([1,2,3],[4,5,6])
Out[11]: [(1, 4), (2, 5), (3, 6)]

Playing around a bit more, I get

In [12]: zip(zip(*a)[0],zip(*b)[0])
Out[12]: [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]

I'm also a big fan of list comprehensions. They are a form of looping, but compact and about as fast as possible with plain Python. Here too I need [0] to pull terms out of the inner lists.

In [25]: [[i[0],j[0]] for i,j in zip(a,b)]
Out[25]: [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

itertools.chain is another good tool for flattening nested lists:

In [31]: zip(*(itertools.chain(*a),itertools.chain(*b)))
Out[31]: [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]

But since you mention numpy we can use:

In [18]: np.concatenate((a,b),axis=1)
Out[18]: 
array([[ 1,  6],
       [ 2,  7],
       [ 3,  8],
       [ 4,  9],
       [ 5, 10]])

The basic concatenate works because np.array(a) produces a (5,1) array. So 2 such arrays can be joined into a (5,2) array without any further shape adjustment.

To get back to the nested list format, use tolist on that array.

In [19]: np.concatenate((a,b),axis=1).tolist()
Out[19]: [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

hstack and column_stack also join on the 1 axis, adjusting dimensions if needed. But I like the explicit control that np.concatenate gives (and requires).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.