140

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.

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
Hellfish
  • 1,685
  • 3
  • 12
  • 10
  • 2
    In other words, you have a list of lists and you want to be able to do work on all members of the inner lists? Also, since all of these inner lists have one value, is it worth ensuring that only the value is inserted into the outer list? Or is it possible for some of the lists to have multiple elements? It's important to give all of the possible information you can, as precisely as possible. – Platinum Azure Jun 29 '12 at 15:34
  • 15
    To help people answer your questions in the future, try to avoid general statements like "the square brackets won't let me" and instead give a specific example of something you tried to do which didn't work, and copy-and-paste a small test code showing the resulting error. – DSM Jun 29 '12 at 15:38
  • related [flatten nested list](http://stackoverflow.com/q/952914/4279) – jfs Jun 29 '12 at 15:41
  • 3
    If they answered your question, you should accept one of these answers – Paul Seeb Mar 07 '14 at 16:33

4 Answers4

218

Flatten the list to "remove the brackets" using a nested list comprehension. This will un-nest each list stored in your list of lists!

list_of_lists = [[180.0], [173.8], [164.2], [156.5], [147.2], [138.2]]
flattened = [val for sublist in list_of_lists for val in sublist]

Nested list comprehensions evaluate in the same manner that they unwrap (i.e. add newline and tab for each new loop. So in this case:

flattened = [val for sublist in list_of_lists for val in sublist]

is equivalent to:

flattened = []
for sublist in list_of_lists:
    for val in sublist:
        flattened.append(val)

The big difference is that the list comp evaluates MUCH faster than the unraveled loop and eliminates the append calls!

If you have multiple items in a sublist the list comp will even flatten that. ie

>>> list_of_lists = [[180.0, 1, 2, 3], [173.8], [164.2], [156.5], [147.2], [138.2]]
>>> flattened  = [val for sublist in list_of_lists for val in sublist]
>>> flattened 
[180.0, 1, 2, 3, 173.8, 164.2, 156.5, 147.2,138.2]
Paul Seeb
  • 6,006
  • 3
  • 26
  • 38
  • 34
    Using `itertools.chain.from_iterable` is much simpler. – Platinum Azure Jun 29 '12 at 15:41
  • 8
    Please explain why. This is about as simple as it gets – Paul Seeb Jun 29 '12 at 15:43
  • 7
    Sorry, I meant more readable/intuitive. Since the OP is having trouble disambiguating between what lists are (sequences of data) and how lists are represented in code (with square brackets), I highly doubt a double list comprehension will make any sense to him/her. – Platinum Azure Jun 29 '12 at 15:50
  • 9
    +1 for being more than twice faster (time it), requires no import and is more compact- – estani Oct 19 '12 at 13:59
  • Love this answer, but I can't figure it out. Can you talk me through how Python evaluates this list comprehension? – ahoffer Aug 26 '14 at 21:07
  • @ahoffer I made some updates. Let me know if that clarifies this. Thanks for the suggestion. – Paul Seeb Aug 28 '14 at 14:26
  • @Paul. Fantastic. Seeing it broken into blocks was enlightening. – ahoffer Aug 28 '14 at 16:52
  • 2
    While the question is a duplicate, I think this answer is superior to any others I've seen. I like list comprehension a lot, but this particular construct remains non-intuitive for some reason. – travc Apr 27 '15 at 19:01
  • @travc I agree ... it seems like this nested list comprehension is intuitively backwards. Seems like it should be `[val for val in (sublist for sublist in list_of_lists)]` or something like that. But that yields the original nested list. Apparently the "nested list comprehension" here is a different structure from what I'm thinking. – LarsH Sep 21 '21 at 01:22
  • This is successful for nested lists of uniform depth, but not something like `['apple', 'pie', ['ham', 'cheese']]` – Merlin May 14 '22 at 20:25
162

I would use itertools.chain - this will also cater for > 1 element in each sublist:

from itertools import chain
list(chain.from_iterable([[180.0], [173.8], [164.2], [156.5], [147.2], [138.2]]))
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • 10
    Why would you import an entire module to do something as simple as this? – Paul Seeb Jun 29 '12 at 15:42
  • 9
    @PaulSeeb simplest, generic, built-in method way of flattening an iterable of iterables... What if the sublists had 100 elements? I certainly wouldn't want to be typing the listcomp code for that one... – Jon Clements Jun 29 '12 at 15:46
  • 3
    if the sublist had 100 elements a nested list comp could still deal with this without importing an entire module. It is mostly just style and preference but personally I see the list comp as more readable as most programmers have used list comps but not all have read the entire itertools library. Not that its difficult to look up but its just one more thing. – Paul Seeb Jun 29 '12 at 15:51
  • 5
    Unfortunately, `chain` has the same shortcoming as a list comprehension with regard to many levels of nesting (that is, it is not recursive). However, I believe `itertools` allows for many nice operations to be done with highly readable code, which is why I still support this answer rather than using a double list comprehension. – Platinum Azure Jun 29 '12 at 15:51
  • @PlatinumAzure I was in the middle of writing that it breaks when more than 1-level deep when the phone rang - so you beat me to it that time! I was also going to mention that if the list doesn't need to be materialised, then just looping over the iterator that chain generates could be an advantage... – Jon Clements Jun 29 '12 at 16:01
  • @JonClements Might as well. In my answer, I had been about to write an example for summing the elements using `reduce`. Go ahead and run with that or something similar :-) – Platinum Azure Jun 29 '12 at 16:22
  • @PlatinumAzure Do-able but ugh - Think I'll take a rain check on that one though ;) – Jon Clements Jun 29 '12 at 16:32
  • Unfortunately, this doesn't distinguish between lists and strings. – Cerin Nov 12 '13 at 21:37
  • @cerin Indeed. It works on purely an iterable of iterables (as do all the other answers here). So yes, a list of strings would most likely result in a non-sensible result. However, that's a different answer which can depend on Python version and wasn't part of this question which was based on lists of single floats. – Jon Clements Nov 12 '13 at 21:43
  • I like your answer very much, but how can flatten [1,[2,3]] ? – len Feb 16 '21 at 18:50
  • This answer is more readable and also more efficient than the double list comprehension. Tested with `import timeit; import itertools; list_of_lists = [list(range(10))] * 1000; timeit.timeit(lambda: [item for sub_list in list_of_lists for item in sub_list], number=10000); timeit.timeit(lambda: list(itertools.chain.from_iterable(list_of_lists)), number=10000)` – Daniel Sep 10 '22 at 20:04
26

Given

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

and your specific question: How can I remove the brackets?

Using list comprehension :

new_d = [i[0] for i in d]

will give you this

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

then you can access individual items with the appropriate index, e.g., new_d[0] will give you 180.0 etc which you can then use for math.

If you are going to have a collection of data, you will have some sort of bracket or parenthesis.

Note, this solution is aimed specifically at your question/problem, it doesn't provide a generalized solution. I.e., it will work for your case.

Levon
  • 138,105
  • 33
  • 200
  • 191
  • 14
    The OP has little idea about lists, giving him/her this solution might cause undesirable effects if s/he wants to use it to flatten multiple elements (no error, just silently return the first...) – estani Oct 19 '12 at 14:03
2
>>> lis=[[180.0], [173.8], [164.2], [156.5], [147.2], [138.2]]
>>> [x[0] for x in lis]
[180.0, 173.8, 164.2, 156.5, 147.2, 138.2]
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504