Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I flatten a list of lists/nested lists? [duplicate]

I have python code like this:

newlist =[[52, None, None], [129, None, None], [56, None, None], [111, None, None],  
          [22, None, None], [33, None, None], [28, None, None], [52, None, None],  
          [52, None, None], [52, None, None], [129, None, None], [56, None, None],  
          [111, None, None], [22, None, None], [33, None, None], [28, None, None]]

I want the newlist like:

newlist =[52, None, None,129, None, None,56, None, None,111, None, None,22, 
          None, None,33, None, None,28, None, None,52, None, None,52, None,  
          None,52, None, None,129, None, None,56, None, None, 111, None,  
          None,22, None, None,33, None, None,28, None, None]

Is there any way to work around ?

like image 787
user2879220 Avatar asked Nov 21 '13 04:11

user2879220


People also ask

How do you make a list of lists flat?

Flatten List of Lists Using sum. Summing over inner lists is another solution. The function has two parameters: iterable which is a list of lists and start which is an empty list in our case that serves as the initial flat list to which items of the inner sublists are added.


4 Answers

What you are trying to do is called flattening the list. And according to the Zen of Python, you are trying to do the right thing. Quoting from that

Flat is better than nested.

  1. So you can use list comprehension like this

    newlist = [item for items in newlist for item in items]
    
  2. Or you can use chain from itertools like this

    from itertools import chain
    newlist = list(chain(*newlist))
    
  3. Or you can use chain.from_iterable, where unpacking of the list is not necessary

    from itertools import chain
    newlist = list(chain.from_iterable(newlist))
    
  4. Using sum function

    newlist = sum(newlist, [])
    
  5. Using reduce function

    newlist = reduce(lambda x,y: x+y, newlist)
    
  6. Using operator.add. This will be faster than the reduce with lambda version.

    import operator
    newlist = reduce(operator.add, newlist)
    

Edit: For the sake of completeness, included the answers found in Making a flat list out of list of lists in Python as well.

I tried to time all of them in Python 2.7, like this

from timeit import timeit
print(timeit("[item for items in newlist for item in items]", "from __main__ import newlist"))
print(timeit("sum(newlist, [])", "from __main__ import newlist"))
print(timeit("reduce(lambda x,y: x+y, newlist)", "from __main__ import newlist"))
print(timeit("reduce(add, newlist)", "from __main__ import newlist; from operator import add"))
print(timeit("list(chain(*newlist))", "from __main__ import newlist; from itertools import chain"))
print(timeit("list(chain.from_iterable(newlist))", "from __main__ import newlist; from itertools import chain"))

Output on my machine

2.26074504852
2.45047688484
3.50180387497
2.56596302986
1.78825688362
1.61612296104

So, the most efficient way to do this is to use list(chain.from_iterable(newlist)), in Python 2.7. Ran the same test in Python 3.3

from timeit import timeit
print(timeit("[item for items in newlist for item in items]", "from __main__ import newlist"))
print(timeit("sum(newlist, [])", "from __main__ import newlist"))
print(timeit("reduce(lambda x,y: x+y, newlist)", "from __main__ import newlist; from functools import reduce"))
print(timeit("reduce(add, newlist)", "from __main__ import newlist; from operator import add; from functools import reduce"))
print(timeit("list(chain(*newlist))", "from __main__ import newlist; from itertools import chain"))
print(timeit("list(chain.from_iterable(newlist))", "from __main__ import newlist; from itertools import chain"))

Output on my machine

2.26074504852
2.45047688484
3.50180387497
2.56596302986
1.78825688362
1.61612296104

So, be it Python 2.7 or 3.3, use list(chain.from_iterable(newlist)) to flatten the nested lists.

like image 109
thefourtheye Avatar answered Oct 17 '22 05:10

thefourtheye


Just the easiest one:

newlist = sum(newlist, [])
print newlist
like image 21
lennon310 Avatar answered Oct 17 '22 04:10

lennon310


Try:

newlist = [j for i in newlist for j in i]
like image 35
Christian Tapia Avatar answered Oct 17 '22 03:10

Christian Tapia


temp = []
for small_list in newlist:
    temp += small_list
newlist = temp

This should do it.

like image 27
tmj Avatar answered Oct 17 '22 05:10

tmj