7

I have a list that contain id number. Some elements of the list is an another list. To convert nested list into a single list, I write a recursive function using collections module.

My codes are following.

from collections import Iterable
def single_list(list):
for item in list:
    if isinstance(item, Iterable):
        yield from single_list(item)
    else:
        yield item

Item_list = [10,20,[30,40],[50,'Null',70],100]
items_single=single_list(Item_list)
for item in items_single:
print(item)

When I run my program, I get the following error message.

  Traceback (most recent call last):
  File "/Research/SoftDev/SEPJ/StackOverflow_qs.py", line 42, in <module>
  for i in items_single:
  File "/Research/SoftDev/SEPJ/StackOverflow_qs.py", line 36, in single_list
  yield from single_list(item)
  File "/Research/SoftDev/SEPJ/StackOverflow_qs.py", line 36, in single_list
  yield from single_list(item)
  File "/Research/SoftDev/SEPJ/StackOverflow_qs.py", line 36, in single_list
  yield from single_list(item)
  [Previous line repeated 986 more times]
  File "/Research/SoftDev/SEPJ/StackOverflow_qs.py", line 35, in single_list
  if isinstance(item, Iterable):
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/abc.py", line 184, in __instancecheck__
if subclass in cls._abc_cache:
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_weakrefset.py", line 75, in __contains__
return wr in self.data
 RecursionError: maximum recursion depth exceeded in comparison

 Process finished with exit code 1

I do not know how to fix the error.

Younus Ali
  • 79
  • 1
  • 4

3 Answers3

7

You are getting the error because of string value contains in the nested list. You need to handle string value as well.

You can fix the error by following codes:

from collections import Iterable

def single_list(list,ignore_types=(str)): 
for item in list:
    if isinstance(item, Iterable) and not isinstance(item, ignore_types):
        yield from single_list(item,ignore_types=(str))
    else:
        yield item

Item_list = [10,20,[30,40],[50,'Null',70],100]
items_single=single_list(Item_list)
for item in items_single:
    print(item)
Reja
  • 898
  • 1
  • 9
  • 21
2

Your question is focused on flattening a list. This question was well answered on StackOverflow, see Making a flat list out of list of lists in Python

Here is my own answer on that thread, though it may not be the best answer.

I recently came across a situation where I had a mix of strings and numeric data in sublists such as

test = ['591212948',
['special', 'assoc', 'of', 'Chicago', 'Jon', 'Doe'],
['Jon'],
['Doe'],
['fl'],
92001,
555555555,
'hello',
['hello2', 'a'],
'b',
['hello33', ['z', 'w'], 'b']]

where methods like flat_list = [item for sublist in test for item in sublist] have not worked. So, I came up with the following solution for 1+ level of sublists

def flattenList(data):
    results = []
    for rec in data:
        if isinstance(rec, list):
            results.extend(rec)
            results = flattenList(results)
        else:
            results.append(rec)
    return results

And the result

In [38]: flattenList(test)
Out[38]:
 Out[60]:
['591212948',
'special',
'assoc',
'of',
'Chicago',
'Jon',
'Doe',
'Jon',
'Doe',
'fl',
92001,
555555555,
'hello',
'hello2',
'a',
'b',
'hello33',
'z',
'w',
'b']
Jon
  • 481
  • 2
  • 8
0

You can try below method. nested_list = Is your list which you want to convert.

Code:

flat_list = [item for sublist in nested_list for item in sublist]

Above code is same as below:

for sublist in nested_list:
    for item in sublist:
        flat_list.append(item)

Thanks!

mannu
  • 108
  • 5
  • Thanks for your support. However, I get error message like TypeError: 'int' object is not iterable from your solution. – Younus Ali Nov 12 '18 at 05:52