2

I have a list that takes the shape

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

which when turned into a numpy array becomes

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

so to be clear, i have a list made up of 2 lists and each of those lists are made up of lists

i want to put it in the form

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

or

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

flatten does not work because it just gives me a list of every component, but i want to keep the lists with the same components together so that i end up with a list of lists. The would be lists of different sizes as well so i don't think the reshape function works either.

The other problem is that in the example i gave the lists are made up of the same number, but in my actual code they are different numbers, so i can't simply tell it to put all of a certain number into each list.

I hope i am clear, if not, i will try and clarify

Alex
  • 185
  • 1
  • 2
  • 9
  • Although it can be done, using numpy with an array of type `object` (no- regular shape rows) loses most of numpy's purpose (speed, usabillity, aplicability of `ufuncs`). – Imanol Luengo Jan 12 '16 at 08:18

2 Answers2

3

You could simply use np.concatenate -

np.concatenate(input_list)

Sample run -

In [19]: input_list = [[1,1],[2,2,2]],[[3,3],[4,4],[5,5,5]]

In [20]: np.concatenate(input_list)
Out[20]: array([[1, 1], [2, 2, 2], [3, 3], [4, 4], [5, 5, 5]], dtype=object)
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • @AntonProtopopov Well `np.hstack`, `np.vstack`, etc. all use `np.concatenate` under the hood, so I guess if `np.concatenate` works right away, so it's all good! :) – Divakar Jan 12 '16 at 10:34
  • 1
    Yes, and also because `np.concatenate` are 3x times faster as from test performance for that case. – Anton Protopopov Jan 12 '16 at 10:36
2

You could use two loops with list comprehension, it works both for lists and np.arrays:

l = [[1,1],[2,2,2]],[[3,3],[4,4],[5,5,5]]
result = [i for sublist in l for i in sublist]
print(result)
[[1, 1], [2, 2, 2], [3, 3], [4, 4], [5, 5, 5]]

If you're not familiar with list comprehension you could use usual loops (equivalent for list comprehension solution):

newlist = []
for sublist in l:
    for i in sublist:
        newlist.append(i)

print(newlist)
[[1, 1], [2, 2, 2], [3, 3], [4, 4], [5, 5, 5]]

EDIT:

Or you could use np.concatenate or np.hstack as @Divakar suggested which are more readable but performance...:

In [225]: %timeit [i for sublist in l for i in sublist]
1000000 loops, best of 3: 885 ns per loop

In [227]: %timeit np.concatenate(l)
100000 loops, best of 3: 4.12 us per loop

In [226]: %timeit np.hstack(l)
100000 loops, best of 3: 13.3 us per loop

EDIT2

From @hpaulj comment you could use itertools.chain(*l) tp achieve with calling list:

import itertools
In [315]: list(itertools.chain(*l))
Out[315]: [[1, 1], [2, 2, 2], [3, 3], [4, 4], [5, 5, 5]]

In [317]: %timeit list(itertools.chain(*l))
1000000 loops, best of 3: 876 ns per loop

So the results are almost the same as for list comprension, may be a bit faster.

Anton Protopopov
  • 30,354
  • 12
  • 88
  • 93
  • Thank you! I will accept your answer in a few minutes...can you tell me what that is called? i would like to look up more information about that. Thank you again! – Alex Jan 12 '16 at 07:53
  • 1
    How about `itertools.chain(*l)`? That's a fast 1 level list flattener idiom. – hpaulj Jan 12 '16 at 12:37