How to flatten a list to return a new list with all the elements?

Question:

I am trying to write a function called flatten_list that takes as input a list which may be nested, and returns a non-nested list with all the elements of the input list.

My code:

def flatten_list(alist):
    """
    >>> flatten_list([1,2,3])
    [1, 2, 3]
    >>> flatten_list([1, [2,3], [4, 5], 6])
    [1, 2, 3, 4, 5, 6]
    """
    flat_list = []
    for element in alist:
        flat_list += element
    return flat_list

This code works for lists with strings, but not integer values. How can I change the code so that it works for both?

thanks

Asked By: codingwarrior

||

Answers:

You can do it as:

a = [1, [2,3], [4, 5], 6]

def flatten(l,result = []):
    if isinstance(l, list):
        for i in l:
            flatten(i)
    else:
        result.append(l)
    return result

>>> print flatten(a)
[1, 2, 3, 4, 5, 6]

This will works for even deeper nesting levels:

>>> print flatten([1, [2, [3, 4]]])
[1, 2, 3, 4]

Demo

Answered By: sshashank124

Generally, this would be done recursively, for example:

def flatten(input_, output=None):
    if output is None:
        output = []
    if isinstance(input_, basestring):
        output.append(input_)
    else:
        for item in input_:
            try:
                flatten(item, output)
            except TypeError:
                output.append(item)
    return output

This will work with any combination of iterable containers (e.g. set, list, tuple, dict (keys only)) and contents (e.g. int, float, str), using the common EAFP Python style. Note the specific exception for strings, which you probably don’t want to be unpacked!

A few examples of usage:

>>> flatten([1, [2, [3, [4, 5], 6], 7], 8])
[1, 2, 3, 4, 5, 6, 7, 8]
>>> flatten([1, "foo", ["bar", 2], 3])
[1, 'foo', 'bar', 2, 3]
>>> flatten([1, (2, 3), {4: 5}])
[1, 2, 3, 4]
>>> flatten("hello")
['hello']

And what happens with non-iterables as direct arguments:

>>> flatten(1)

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    flatten(1)
  File "<pyshell#1>", line 4, in flatten
    for item in input_:
TypeError: 'int' object is not iterable
Answered By: jonrsharpe

using collections.Iterable

from collections import Iterable
def flatten(items):
    for elem in items:
        if isinstance(elem,Iterable) and not isinstance(elem,str):
            for sub_elem in flatten(elem):
                yield sub_elem
        else:
            yield elem




 In [15]:   print list(flatten((1, (2,3), [4, 5],{10,11,12}, 6)))
 [1, 2, 3, 4, 5, 10, 11, 12, 6]


 In [16]: print list(flatten((1, (2,3), (4,5,6), 6)))
 [1, 2, 3, 4, 5, 6, 6]

 In [17]: print list(flatten([1, "foo", ["bar", 2], 3]))
 [1, 'foo', 'bar', 2, 3]
Answered By: Padraic Cunningham
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.