Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a nested list into a one-dimensional list in Python?

I tried everything (in my knowledge) from splitting the array and joining them up together and even using itertools:

import itertools

def oneDArray(x):
    return list(itertools.chain(*x))

The result I want:

a) print oneDArray([1,[2,2,2],4]) == [1,2,2,2,4]

Strangely, it works for

b) print oneDArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == [1, 2, 3, 4, 5, 6, 7, 8, 9]

Question 1) How do I get part a to work the way I want (any hints?)

Question 2) Why does the following code above work for part b and not part a??

like image 852
compski Avatar asked Jul 05 '13 09:07

compski


People also ask

How do I make a nested list single list in Python?

The task is to convert a nested list into a single list in python i.e no matter how many levels of nesting is there in the python list, all the nested have to be removed in order to convert it to a single containing all the values of all the lists inside the outermost brackets but without any brackets inside.

How do I convert a list to a single list in Python?

To make this more readable, you can make a simple function: def flatten_list(deep_list: list[list[object]]): return list(chain.

How do I merge nested lists in Python?

First, flatten the nested lists. Take Intersection using filter() and save it to 'lst3'. Now find elements either not in lst1 or in lst2, and save them to 'temp'. Finally, append 'temp' to 'lst3'.


6 Answers

You need to recursively loop over the list and check if an item is iterable(strings are iterable too, but skip them) or not.

itertools.chain will not work for [1,[2,2,2],4] because it requires all of it's items to be iterable, but 1 and 4 (integers) are not iterable. That's why it worked for the second one because it's a list of lists.

>>> from collections import Iterable
def flatten(lis):
     for item in lis:
         if isinstance(item, Iterable) and not isinstance(item, str):
             for x in flatten(item):
                 yield x
         else:        
             yield item

>>> lis = [1,[2,2,2],4]
>>> list(flatten(lis))
[1, 2, 2, 2, 4]
>>> list(flatten([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Works for any level of nesting:

>>> a = [1,[2,2,[2]],4]
>>> list(flatten(a))
[1, 2, 2, 2, 4]

Unlike other solutions, this will work for strings as well:

>>> lis = [1,[2,2,2],"456"]
>>> list(flatten(lis))
[1, 2, 2, 2, '456']
like image 108
Ashwini Chaudhary Avatar answered Oct 13 '22 10:10

Ashwini Chaudhary


If you're using python < 3 then you can do the following:

from compiler.ast import flatten
list = [1,[2,2,2],4]
print flatten(list)

The manual equivalent in python 3.0 would be (taken from this answer):

def flatten(x):
    result = []
    for el in x:
        if hasattr(el, "__iter__") and not isinstance(el, str):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

 print(flatten(["junk",["nested stuff"],[],[[]]]))  

You could even do the same in a list comprehension:

list = [1,[2,2,2],4]
l = [item for sublist in list for item in sublist]

Which is the equivalent of:

l = [[1], [2], [3], [4], [5]]
result = []
for sublist in l:
    for item in sublist:
        result.append(item)

print(result)
like image 38
Ewan Avatar answered Oct 13 '22 10:10

Ewan


To Make A Single list from a Nested List in python we can simply do this :

from functools import reduce

some_list = [[14], [215, 383, 87], [298], [374], [2,3,4,5,6,7]]
single_list = reduce(lambda x,y: x+y, some_list)
print(single_list)

Output: [14, 215, 383, 87, 298, 374, 2, 3, 4, 5, 6, 7]

like image 32
Nabajeet Dhar Avatar answered Oct 13 '22 10:10

Nabajeet Dhar


from nltk import flatten

example_list = [1, [2, 3], 3]
flattened_list = flatten(example_list)
print(flattened_list)

Output: [1, 2, 3, 3]

like image 41
Brndn Avatar answered Oct 13 '22 10:10

Brndn


itertools.chain() iterates through each item in the inputted list (refer to the docs I linked). Because you can't iterate through integers, the error is raised. That is why in the second example, you only have lists in the list and no integers alone, thus no integers are actually being iterated through.

To get it working, you can use recursion:

>>> from collections import Iterable
>>> def flat(lst):
...     for parent in lst:
...         if not isinstance(i, Iterable):
...             yield parent
...         else:
...             for child in flat(parent):
...                 yield child
...
>>> list(flat(([1,[2,2,2],4]))
[1, 2, 2, 2, 4]
like image 23
TerryA Avatar answered Oct 13 '22 11:10

TerryA


Use more_itertools

import more_itertools

nested_test1 = [[-1, -2], [1, 2, 3, [4, (5, [6, 7])]], (30, 40), [25, 35]]
nested_test2 = [1,[2,2,2],4]
lis = [1,[2,2,2],"456"]

print(list(more_itertools.collapse(nested_test1)))
print(list(more_itertools.collapse(nested_test2)))
print(list(more_itertools.collapse(lis)))

OUTPUT

[-1, -2, 1, 2, 3, 4, 5, 6, 7, 30, 40, 25, 35]
[1, 2, 2, 2, 4]
[1, 2, 2, 2, '456']
like image 26
Akshay Kumbharkar Avatar answered Oct 13 '22 11:10

Akshay Kumbharkar