【问题标题】:Recursion removing list elements Python递归删除列表元素Python
【发布时间】:2018-01-09 09:40:48
【问题描述】:

需要编写一个递归函数来删除列表的元素,但将数组保留在结果中,例如。

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"]]) 将返回 [[]]

我的代码由于某种原因返回 ["b",[]],它缺少一个元素。

【问题讨论】:

  • 您在迭代时删除了 list 的元素。不要不要那样做。您删除第一个元素,当索引继续移动时,新的第二个元素是以前的第三个元素......找到一种方法来避免这种情况!
  • 您在迭代时从列表中删除元素,因此只需在函数内创建列表副本并返回该列表
  • 想要就地修改您的列表,还是可以创建一个新列表?
  • 你能提供一个使用这个逻辑的代码示例吗? @tobias_k 没关系,只需要返回正确的嵌套列表即可。
  • 为什么要指定递归解决方案?将迭代方法 (for) 与递归混合是很奇怪的。如果你想要一个递归的解决方案,这不是一个很好的开始。

标签: python recursion tail-recursion


【解决方案1】:

在迭代集合时不要从集合中移除元素。重复调用list.remove 在性能方面也不是理想的,因为每次删除(从随机索引)都是O(N)。解决这两个问题的简单方法是以下理解:

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

看似缺少的基本情况是一个没有嵌套列表的列表,其中返回一个空列表。

如果要就地修改列表,可以使用切片赋值:

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

【讨论】:

    【解决方案2】:
    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"]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-11
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 2019-07-21
      相关资源
      最近更新 更多