Flatten an Irregular List of Lists

Flatten an irregular list of lists

Using generator functions can make your example easier to read and improve performance.

Python 2

Using the Iterable ABC added in 2.6:

from collections import Iterable

def flatten(xs):
for x in xs:
if isinstance(x, Iterable) and not isinstance(x, basestring):
for item in flatten(x):
yield item
else:
yield x

Python 3

In Python 3, basestring is no more, but the tuple (str, bytes) gives the same effect. Also, the yield from operator returns an item from a generator one at a time.

from collections.abc import Iterable

def flatten(xs):
for x in xs:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
yield from flatten(x)
else:
yield x

Flatten an irregular list of lists

Using generator functions can make your example easier to read and improve performance.

Python 2

Using the Iterable ABC added in 2.6:

from collections import Iterable

def flatten(xs):
for x in xs:
if isinstance(x, Iterable) and not isinstance(x, basestring):
for item in flatten(x):
yield item
else:
yield x

Python 3

In Python 3, basestring is no more, but the tuple (str, bytes) gives the same effect. Also, the yield from operator returns an item from a generator one at a time.

from collections.abc import Iterable

def flatten(xs):
for x in xs:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
yield from flatten(x)
else:
yield x

How to flatten a hetrogenous list of list into a single list in python?

Here is a relatively simple recursive version which will flatten any depth of list

l = [35,53,[525,6743],64,63,[743,754,757]]

def flatten(xs):
result = []
if isinstance(xs, (list, tuple)):
for x in xs:
result.extend(flatten(x))
else:
result.append(xs)
return result

print flatten(l)

Flatten an irregular list of lists in Python recursively

Your code is relying on a global; if the checker calls your function twice, it'll receive a longer list than expected:

>>> t = []
>>> def flatten(aList):
... for i in aList:
... if type(i) !=list:
... t.append(i)
... else:
... flatten(i)
... return t
...
>>> flatten([1, 1])
[1, 1]
>>> flatten([1, 1])
[1, 1, 1, 1]
>>> t # your global, still holding all those values:
[1, 1, 1, 1]

Don't use globals. Use a local list, and and extend it with the result of recursive calls:

def flatten(aList):
t = []
for i in aList:
if not isinstance(i, list):
t.append(i)
else:
t.extend(flatten(i))
return t

Note that I switched to using isinstance() to test for the type. This version doesn't suffer from shared state leaking into the next call:

>>> def flatten(aList):
... t = []
... for i in aList:
... if not isinstance(i, list):
... t.append(i)
... else:
... t.extend(flatten(i))
... return t
...
>>> flatten([1, 1])
[1, 1]
>>> flatten([1, 1])
[1, 1]
>>> flatten([[[1]], [[[5]]]])
[1, 5]
>>> flatten([1, 1, [42, 81]])
[1, 1, 42, 81]

Convert an irregular list with multiple levels of nested lists to a list of lists

Generator function flatten is passed a list and looks at each sublist. If the length of the sublist is 0 or if the first element of the sublist is not another list, it just yields the sublist as the next list to be added to the result. Otherwise it recursively processes the sublist. Function nested_to_listoflist just assembles all of the "yielded" lists into one final list.

def flatten(l):
for el in l:
if not el or not isinstance(el[0], list):
yield el
else:
yield from flatten(el)

def nested_to_listoflist(l):
return [el for el in flatten(l)]
# or return list(flatten(l))


nested_list = [[[1, 2, 3], [[5, 6, 7], [8, 9, 10, 11, 23]]], [4], [[12, 13, 14], [[15, 16], [[17, 18], [19, 20]]]], [21, 22, 25, 26]]
unnested_list = nested_to_listoflist(nested_list)
print(unnested_list)

Prints:

[[1, 2, 3], [5, 6, 7], [8, 9, 10, 11, 23], [4], [12, 13, 14], [15, 16], [17, 18], [19, 20], [21, 22, 25, 26]]

Python Demo

Flatten a list of lists independent on content types and length and depth of sublists

import pydash 
l = ["af", 2, [4.123, "ic", [-8, ["xdr"], -6]], [], [-2]]
pydash.flatten_depth(l,-1)
# output: ['af', 2, 4.123, 'ic', -8, 'xdr', -6, -2]

Flattening a list of strings and lists to work on each item

A more concise approach is:

for entry in initial_list:
for term in ([entry] if isinstance(entry, str) else entry):
do_something(term)

Flatten (an irregular) list of lists in Python respecting Pandas Dataframes

That flatten function will recurse down if the element is an instance of collections.Iterable and it's not a string (which is iterable, but we usually want to treat it as a scalar, something we're not going to look inside).

Even though DataFrames are instances of collections.Iterable, it sounds like you want them to be terminal too. In that case:

    if (isinstance(el, collections.Iterable) and 
not isinstance(el, (basestring, pandas.DataFrame))):

After which:

>>> list(flatten([[1,2], "2", df]))
[1, 2, '2', <class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 0 to 99
Data columns (total 4 columns):
A 100 non-null values
B 100 non-null values
C 100 non-null values
D 100 non-null values


Related Topics



Leave a reply



Submit