Flatten list of lists


Question

I'm having a problem with square brackets in Python. I wrote a code that produces the following output:

[[180.0], [173.8], [164.2], [156.5], [147.2], [138.2]]

But I would like to perform some calculations with that, but the the square brackets won't let me.

How can I remove the brackets? I saw some examples to do that but I could not apply them to this case.

1
82
11/26/2012 2:55:22 PM

Accepted Answer

If you're just looking to iterate over a flattened version of the data structure and don't need an indexable sequence, consider itertools.chain and company.

>>> list_of_menuitems = [['image00', 'image01'], ['image10'], []]
>>> import itertools
>>> chain = itertools.chain(*list_of_menuitems)
>>> print(list(chain))
['image00', 'image01', 'image10']

It will work on anything that's iterable, which should include Django's iterable QuerySets, which it appears that you're using in the question.

Edit: This is probably as good as a reduce anyway, because reduce will have the same overhead copying the items into the list that's being extended. chain will only incur this (same) overhead if you run list(chain) at the end.

Meta-Edit: Actually, it's less overhead than the question's proposed solution, because you throw away the temporary lists you create when you extend the original with the temporary.

Edit: As J.F. Sebastian says itertools.chain.from_iterable avoids the unpacking and you should use that to avoid * magic, but the timeit app shows negligible performance difference.

288
5/23/2017 12:26:37 PM

You almost have it! The way to do nested list comprehensions is to put the for statements in the same order as they would go in regular nested for statements.

Thus, this

for inner_list in outer_list:
    for item in inner_list:
        ...

corresponds to

[... for inner_list in outer_list for item in inner_list]

So you want

[image for menuitem in list_of_menuitems for image in menuitem]

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon