2

I'm trying to create a recursive function which takes an input list (with nested lists) and removes all elements that match elements from a second input array. I currently have this:

def removeElements(self, array, remove_elements):

    for element in array:
        if isinstance(element, list):
            removeElements(element, remove_elements)
        else:
            for remove_element in remove_elements:
                if element == remove_element:
                    array.remove(element)

    return array

The 'array' input generally looks something like this:

array = [[1], [[2,3,4],[5,6,7]], [8,9,10]]

And the 'remove_elements' array is never nested and looks something like this:

remove_elements = [2,4,6,8,10]

This generally works as expected until I give the following remove_elements array:

[1,2,3,4,5,6,7,8,9,10]

Output:

[[], [[3], [6]], [9]]

For some reason, when I try to run it on every single element it doesn't remove the 2nd index of nested lists that have more than 1 element. I would like the function to also just return a completely empty list if that's possible, but I don't know what I'm doing wrong.

  • why tagged 2.7? i think the same code should work in python3 – Lei Yang Jul 15 '21 at 13:00
  • @LeiYang, my bad, I have to work in 2.7 for this particular project so I wanted to be as clear as possible. I'll remove it – Bo Kamphues Jul 15 '21 at 13:05
  • Every time you remove from the array, the iteration carries on as if the list was the same size, thus every odd index in the inner arrays is missed – ChrisOram Jul 15 '21 at 13:13
  • @ChrisOram, of course, makes total sense. I should have done it the better way by creating a new array and returning that in the first place! Thanks for the help – Bo Kamphues Jul 15 '21 at 13:17
  • 1
    @BoKamphues Its a great learning. I love it when something like that comes along and makes you say "what?!" – ChrisOram Jul 15 '21 at 14:49

1 Answers1

2

Modifying an array while you're iterating over it leads to all kinds of strangeness; there's a decent explanation here. You can get around it by building a new output array like so:

def removeElements(array, remove_elements):

    out = []
    for element in array:
        if isinstance(element, list):
            out.append(removeElements(element, remove_elements))
        else:
            if element not in remove_elements:
                out.append(element)

    return out
Simon Brahan
  • 2,016
  • 1
  • 14
  • 22