0

I've been scouring Google for an answer to this question, and have so far only seen similar results for different problems.

My list of lists of lists has the structure as follows (edit: arrays are numpy): [array([[item]]), array([[item2]]), ...]

As you can see, it is not inconsistent formatting (it's a result of using numpy column vectors in a previous operation). I would like to flatten this to a simple list of values using a 1-line list comprehension. Similar problems include variable size sub- or sub-sub-lists, which I do not have to worry about.

The "solution" that would make the most sense to me: [item for sublist for arr in list for item in sublist in arr] But this doesn't work for syntax reasons, not to mention that I'm unsure if it goes deep enough.

I was wondering if this is even possible, and if anyone smarter than me could come up with a solution. Not time sensitive, we've settle for scatter plots...for now.

Cheers!

  • 3
    Please provide an example. What is `array`? Is it `np.array`? What do you mean by "doesn't work for syntax reasons"? Please provide the exact error (and of course your code that produces that error). What do you mean by "I'm unsure if it goes deep enough."? Does your input have deeper nesting? You really need a concrete example. – j1-lee Nov 15 '21 at 05:07
  • What do you think `for sublist for arr in list` and `for item in sublist in arr` mean? Note that `for ... in ...` is *one* syntax element, not a combination of two separate ones. – MisterMiyagi Nov 15 '21 at 05:43
  • `[arr.tolist() for arr in alist]` would be a start. Maybe use a `arr.ravel().tolist()` or even `arr.item()` where appropriate. – hpaulj Nov 15 '21 at 07:57
  • 1
    For better answers, provide a [mcve] – hpaulj Nov 15 '21 at 08:19
  • @j1-lee, yes it's a numpy array. I apologize, I assumed the "numpy" tag and the reference to numpy operations implied this, but I should have been more clear. @MisterMiyagi, I see that `for ... in ...` is one syntax element, as I do simple list comprehension regularly. However, I'm still trying to decipher the mechanics of nested list comprehension and that was my best guess for triple-layered considering that double-layered follows as `item for sublist in list for item in sublist` per [this](https://stackoverflow.com/questions/952914/how-to-make-a-flat-list-out-of-a-list-of-lists) post. – Sparky Parky Nov 15 '21 at 19:57
  • @j1-lee the provided pseudo-code returns a generalized "improper syntax" error in my editor. The "I'm unsure if it goes deep enough" was referring simply to the fact that, with what I was trying, it appeared I may have needed a layer even deeper due to the `[array([[item]])]` structure. With this, it appears to me as 4 total layers, but I was unsure if triple-layered list comprehension would suffice due to the fact that array([item]) typically returns a single list. Just not entirely clear on numpy handling in that instance/statement. – Sparky Parky Nov 15 '21 at 20:02
  • @hpaulj `[arr.tolist() for arr in alist]` is a good start, and where I began. It still returns a list of lists of lists though. `[arr.item() for arr in alist]`, however, works perfectly and I feel a little silly for not thinking of it. Thank you! – Sparky Parky Nov 15 '21 at 20:10

1 Answers1

0

If your arrays are of one element as you've shown, you can directly index down when you do your comprehension:

list_of_lists_of_lists = [[[item1]], [[item2]], ...]
[array[0][0] for array in list_of_lists_of_lists]

If your arrays are more complicated, you can do your nested for x in y statements, you just need to put them in the correct order:

list_of_lists_of_lists = [[[item1]], [[item2], [item5]], [[item3, item4]]]
[item for lists_of_lists in list_of_lists_of_lists for sublist in lists_of_lists for item in sublist]

Which will yield them in the order:

[item1, item2, item5, item3, item4]

Lastly, if you don't know how deep it goes but you do know the type of your items, you can always perform a recursive search:

test = [[[1]], [[2], [5]], [[[3], 4]], [[[[[[6]]]]]]]
result = list()
my_type = int
def generator(my_list, accumulator):
    if isinstance(my_list, my_type):
        accumulator.append(my_list)
        return
    for item in my_list:
        generator(item, accumulator)
gen(test, result)

Which will give you result = [1, 2, 5, 3, 4, 6]

rcanty
  • 54
  • 5
  • Your initial `[array[0][0] for array in list_of_lists_of_lists]` works perfectly, as does @hpaulj's `[arr.item() for arr in alist]` and I now feel silly for not thinking of either of these. I'll pass the blame onto the 10-hour coding session that lead up to this question. I also appreciate your inclusion of deep-nested list comprehension syntax for these purposes, which I'm sure I'll use in the future. Thank you! – Sparky Parky Nov 15 '21 at 20:14