Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flatten list of list through list comprehension

I am trying to flatten a list using list comprehension in python. My list is somewhat like

[[1, 2, 3], [4, 5, 6], 7, 8]

just for printing then individual item in this list of list I wrote this code

   def flat(listoflist):
     for item in listoflist:
             if type(item) != list:
                     print item
             else:
                     for num in item:
                             print num  
>>> flat(list1)
1
2
3
4
5
6
7
8

Then I used the same logic to flatten my list through list comprehension I am getting the following error

    list2 = [item if type(item) != list else num for num in item for item in list1]
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: 'int' object is not iterable

How can I flatten this type of list-of-list using using list comprehension ?

like image 367
Anurag Sharma Avatar asked Jun 27 '13 09:06

Anurag Sharma


People also ask

What does it mean to flatten a list?

Flattening lists means converting a multidimensional or nested list into a one-dimensional list. For example, the process of converting this [[1,2], [3,4]] list to [1,2,3,4] is called flattening.

How do you take a list out of a list in Python?

In Python, use list methods clear() , pop() , and remove() to remove items (elements) from a list. It is also possible to delete items using del statement by specifying a position or range with an index or slice.


2 Answers

No-one has given the usual answer:

def flat(l):
  return [y for x in l for y in x]

There are dupes of this question floating around StackOverflow.

like image 151
GreenAsJade Avatar answered Sep 19 '22 11:09

GreenAsJade


>>> from collections import Iterable
>>> from itertools import chain

One-liner:

>>> list(chain.from_iterable(item if isinstance(item,Iterable) and
                    not isinstance(item, basestring) else [item] for item in lis))
[1, 2, 3, 4, 5, 6, 7, 8]

A readable version:

>>> def func(x):                                         #use `str` in py3.x 
...     if isinstance(x, Iterable) and not isinstance(x, basestring): 
...         return x
...     return [x]
... 
>>> list(chain.from_iterable(func(x) for x in lis))
[1, 2, 3, 4, 5, 6, 7, 8]
#works for strings as well
>>> lis = [[1, 2, 3], [4, 5, 6], 7, 8, "foobar"]
>>> list(chain.from_iterable(func(x) for x in lis))                                                                
[1, 2, 3, 4, 5, 6, 7, 8, 'foobar']

Using nested list comprehension:(Going to be slow compared to itertools.chain):

>>> [ele for item in (func(x) for x in lis) for ele in item]
[1, 2, 3, 4, 5, 6, 7, 8, 'foobar']
like image 36
Ashwini Chaudhary Avatar answered Sep 18 '22 11:09

Ashwini Chaudhary