-1

solved this task:

Turn a nested list into a flat list Imagine that we have a list of integers with unlimited nesting. That is, our list can consist of lists, which can also have lists inside them. Your task is to turn it all into a linear list with the function flatten

flatten([1, [2, 3, [4]], 5]) => [1, 2, 3, 4, 5]

flatten([1, [2, 3], [[2], 5], 6]) => [1, 2, 3, 2, 5, 6]

flatten([[[[9]], [1, 2], [[8]]) => [9, 1, 2, 8]

The for loop is not working correctly :/

Why is list type ignored in this case?

def flatten(sp: list, b=[]) -> list:
    if len(sp) == 0:
        print(b)
    for i in sp:
        if type(i) == list:
            flatten(i)
        elif type(i) == int:
            b.append(i)
            sp.remove(i)

And that doesn't happen in this?

for i in [1, [2, 3, [4]], 5]:
    if type(i) == list:
        print('YES')

In the end, the task was solved as follows:

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

Please explain why this is so

obito
  • 3
  • 1
  • 2
    Your final code is buggy too. See: https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument – AKX Mar 02 '23 at 11:12
  • 3
    As a general rule, don't mutate (in this case removing elements using `sp.remove(i)`) from a iterable you are iterating through. – Shorn Mar 02 '23 at 11:17
  • 1
    Please not that for very deep lists (thousands), the recursive approach will hit the recursion depth limit and fail. – pts Mar 02 '23 at 11:37

1 Answers1

0

I'd be less concerned with your type checking logic in your original code and more concerned with this aspect of it:

sp = [1, 2, 3]

for i in sp:
    print(i)
    sp.remove(i)

You're modifying the list over which you're iterating so the output is:

1
3

I.e. you're skipping over items. As far as your final solution, I see two issue with it. First, for i in lst isn't recursion! Second, your new_lst = [] argument keeps your code from being reused in the same program:

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

outputs:

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

Here's my attempt at a solution that tries to address both of these issues:

def flatten(thing):
    if isinstance(thing, list):
        if thing:
            return flatten(thing[0]) + flatten(thing[1:])

        return thing

    return [thing]

Perhaps a starting point if not a complete solution.

cdlane
  • 40,441
  • 5
  • 32
  • 81