pythonlistpython-2.7list-comprehension

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 function:

def flat(listoflist):
    for item in listoflist:
        if type(item) != list:
            print(item)
        else:
            for num in item:
                print(num)

interactive output:

>>> 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]

Which gives me the following error:

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 ?


Solution

  • >>> 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']