0

need to write a recurive function to remove elements of list but keep the arrays in the result such as.

def remove_words(listx):
    for element in listx:
        if isinstance(element, list):
            remove_words(element)
        else:
            listx.remove(element)

    return listx

remove_words(["a", "b", ["c"]]) would return [[]]

My code returns ["b",[]] for some reason it's missing an element.

Poiz
  • 7,611
  • 2
  • 15
  • 17
King
  • 11
  • 1
  • 5
  • 2
    You remove an element of a `list` while iterating it. Do **not** do that. You remove the first element and when the index moves on, the new second element is the formerly third... find a way to avoid that! – user2390182 Jan 09 '18 at 09:46
  • You are removing element from list while iterating so just create a copy of list inside function and return that list – Vaseem Ahmed Khan Jan 09 '18 at 09:48
  • Do you _want_ to modify your list in-place, or can you create a new list? – tobias_k Jan 09 '18 at 09:59
  • Can you provide a code example using this logic please? @tobias_k It doesn't matter, just needs to return proper nested lists. – King Jan 09 '18 at 10:03
  • Why did you specify a recursive solution? Mixing an iterative approach (for) with recursion is odd. If you want a recursive solution, this is not a very good start. – Tim Richardson Jan 09 '18 at 10:06
  • @TimRichardson I disagree. OP basically has a tree with arbitrary depth and unknown number of children. The first calls for recursion, the second for iteration. (It certainly _could_ be done purely recursively or iteratively, but I think the basic approach is sound, apart from the modify-while-iterating problem.) – tobias_k Jan 09 '18 at 10:13
  • OK, I jumped to conclusions (reputation of 1 point, name is student127). I disagree that it is sound: it is buggy, hard to read and poorly performant :) – Tim Richardson Jan 09 '18 at 10:26
  • I deleted my hint. – Tim Richardson Jan 09 '18 at 10:41
  • Possible duplicate of [Recursively emptying a nested list while preserving its structure](https://stackoverflow.com/questions/48245128/recursively-emptying-a-nested-list-while-preserving-its-structure) – Mulan Jan 14 '18 at 03:58

2 Answers2

2

Do not remove elements from a collection while iterating it. Repeated calls to list.remove are also not ideal performance-wise since each removal (from a random index) is O(N). A simple way around both issues would be the following comprehension:

def remove_words(listx):
    return [remove_words(e) for e in listx if isinstance(e, list)]

The seemingly missing base case is a list with no nested lists where an empty list is returned.

If you want to modify the list in-place, you can use slice assignment:

def remove_words(listx):
    listx[:] = [remove_words(e) for e in listx if isinstance(e, list)]
user2390182
  • 72,016
  • 6
  • 67
  • 89
0
def remove_words(listx):
  if listx == []:
    return []
  elif not isinstance(listx[0], list):
    return remove_words(listx[1:])
  else:
    return [remove_words(listx[0])] + remove_words(listx[1:])

print(remove_words(["a", "b", ["c"]]))
print(remove_words(["a", ["b",["c","d"],"c"], [["f"],["g"]],"h"]))
englealuze
  • 1,445
  • 12
  • 19