0

I want to flat a list that has nested and not nested elements. From this solution I've tried and it works if all elements within mylist were lists, but in mylist I have simple text strings and nested lists.

My list is like this:

mylist = [
        'tz',
        '7',
        ['a', 'b', 'c'], 
        [['2'], ['4', 'r'], ['34']], 
        [['7'], ['3',  ['2', ['1']]], ['9']], 
        [['11',['7','w']], 'U1', ['0']]
    ]

And my current code is this, getting the error below:

import collections#.abc

def flatten(l):
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
            yield from flatten(el)
        else:
            yield el

            
mylist1=[list(flatten(sublist)) if type(sublist) is list else sublist for sublist in mylist]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
  File "<stdin>", line 3, in flatten
TypeError: isinstance() arg 2 must be a type or tuple of types
>>>

My expected output would be like this

mylist1 = [
        'tz',
        '7',
        ['a', 'b', 'c'], 
        ['2', '4', 'r','34'], 
        ['7','3','2','1','9'],
        ['11','7','w','U1','0']
    ]

What is missing to fix this? thanks.

UPDATE

Now I'm getting this error with code suggested by @Alok

>>> for item in mylist:
...     # if the item in mylist is a list, pass it to your flatten method else
...     # add it to the final list
...     if isinstance(item, list):
...         final_list.append(list(flatten(item)))
...     else:
...         final_list.append(item)
...
Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
  File "<stdin>", line 3, in flatten
TypeError: isinstance() arg 2 must be a type or tuple of types
Ger Cas
  • 2,188
  • 2
  • 18
  • 45
  • Hey Ger, check out the answer, and let me know if that was the solution you were looking for :) – Alok Jun 29 '20 at 07:06

1 Answers1

1

The problem is with some instances which I will point out:

  1. Python 3.x is not following collections.Iterable anymore, you need to import the items from collections.abc and always do try-catch for any import error
try:
    from collections.abc import Iterable
except ImportError:
    from collections import Iterable 
  1. Not utilizing your flatten method appropriately, the method, returns the data, but you have to store it in the form of a list and append it to the final answer list YOUR SUB ARRAYS ONLY BE PASSED INTO THIS METHOD
data.append(list(flatten(item)))

FINAL SOLUTION:

try:
    from collections.abc import Iterable
except ImportError:
    from collections import Iterable 

mylist = [
    'tz',
    '7',
    ['a', 'b', 'c'], 
    [['2'], ['4', 'r'], ['34']], 
    [['7'], ['3',  ['2', ['1']]], ['9']], 
    [['11',['7','w']], 'U1', ['0']]
]

def flatten(l):
    for el in l:
        if isinstance(el, Iterable) and not isinstance(el, (str, bytes)):
            yield from flatten(el)
        else:
            yield el
            
final_list = []
for item in mylist:
    # if the item in mylist is a list, pass it to your flatten method else
    # add it to the final list
    if isinstance(item, type([])): final_list.append(list(flatten(item)))
    else: final_list.append(item)
    
print(final_list)

OUTPUT

['tz', '7', ['a', 'b', 'c'], ['2', '4', 'r', '34'], ['7', '3', '2', '1', '9'], ['11', '7', 'w', 'U1', '0']]

I hope you can achieve your desired output in this way.

Alok
  • 8,452
  • 13
  • 55
  • 93
  • Hello Alok, Thanks for your help. I copy/paste your entire code and still getting error. This time the error I show below the update I've done on original post. – Ger Cas Jun 29 '20 at 15:54
  • 1
    Which python version are you using @GerCas? Can you do it, and let me know if that works for you: `isinstance(names, type(list))` or `isinstance(names, type([]))`. Also, I have already tested the code, and it works as expected. Let me know asap, and we will do something out to help you on this – Alok Jun 29 '20 at 17:05
  • Hi @Alok, python version is 3.8.2. I've tried both options and only worked using this one `if isinstance(item, type([])):` Thanks so much for your help. – Ger Cas Jun 29 '20 at 17:18
  • 1
    Thank you for your kindness in writing. Keep it up in that way. Normally comments on this site tend to be rough and depersonalized. – Ger Cas Jun 29 '20 at 17:49
  • Hey @GerCas, thanks a lot for the big compliment. I would definitely take your advice/compliment with me and move forward. It is a two way thing, see, you learnt something from it, and I learnt from you as well. Thanks for those words. :) – Alok Jun 30 '20 at 05:21