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
An alternative solution using a generator:
import collections
def flatten(iterable):
for item in iterable:
if isinstance(item, collections.Iterable) and not isinstance(item, str): # `basestring` < 3.x
yield from item # `for subitem in item: yield item` < 3.3
else:
yield item
>>> list(flatten([[1, 2, 3], [4, 5, 6], 7, 8]))
[1, 2, 3, 4, 5, 6, 7, 8]
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.
You're trying to iterate through a number, which you can't do (hence the error).
If you're using python 2.7:
>>> from compiler.ast import flatten
>>> flatten(l)
[1, 2, 3, 4, 5, 6, 7, 8]
But do note that the module is now deprecated, and no longer exists in Python 3
def nnl(nl): # non nested list
nn = []
for x in nl:
if type(x) == type(5):
nn.append(x)
if type(x) == type([]):
n = nnl(x)
for y in n:
nn.append(y)
return nn
print (nnl([[9, 4, 5], [3, 8,[5]], 6])) # output: [9, 4, 5, 3, 8, 5, 6]
>>> 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']