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
1
  • Hey Ger, check out the answer, and let me know if that was the solution you were looking for :) Commented Jun 29, 2020 at 7:06

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
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
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.
Thank you for your kindness in writing. Keep it up in that way. Normally comments on this site tend to be rough and depersonalized.
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. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.