【问题标题】:recursive way to go through a nested list and remove all of a select value遍历嵌套列表并删除所有选择值的递归方式
【发布时间】:2016-02-24 20:06:21
【问题描述】:

我正在尝试以递归方式从嵌套列表中删除所有空列表。

def listcleaner(lst):
   if isinstance(lst[0], int):
      return listcleaner(lst[1:])


   if isinstance(lst[0], list):
     if len(lst[0]) == []:
        lst[0].remove([])
        return listcleaner(lst)
     return listcleaner(lst[0])
   return lst

我想要这个函数做的是

>>> a = listcleaner([1, [], [2, []], 5])
>>> print(a)
[1, [2], 5]

【问题讨论】:

  • 您当前的代码有什么问题?
  • >>> listcleaner([1, [2, []], []]) 它会运行并让我回到多行,然后说列表索引超出范围
  • 这不是一个合适的问题。你不能对技术有偏见。这是编程!

标签: python recursion


【解决方案1】:

每次返回时,您都在退出该功能。这是更新的代码:

def listcleaner(lst):
    if not lst:   # If list is empty
        return [] # Go no further
    if isinstance(lst[0], list):
        if lst[0]: # If the list has something in it, we want to run listcleaner() on it.
            return [listcleaner(lst[0])] + listcleaner(lst[1:])
        else: # Otherwise, just skip that list
            return listcleaner(lst[1:])
    else:
        return [lst[0]] + listcleaner(lst[1:]) # If it is not a list, return it unchanged plus listcleaner() on the rest.

a = listcleaner([1, [], [2, []], 5]) 
print(a)

输出:

[1, [2], 5]

【讨论】:

  • 这不是递归的
  • 这取决于我必须走多远才能算作递归。如果您通读整个代码,您会看到我确实再次调用listcleaner() 来清理子列表。
  • 它不能使用 for 或 while 循环。只有 if 语句。
  • @YousufMadi:listcleaner() 返回[1, 2, 5] 可以吗?我已经写了一些可以做到这一点的东西,但我仍在努力将2 保留为列表。
  • @YousufMadi:我刚刚更新了我的答案。它没有forwhile 循环;只是if 声明。
【解决方案2】:

希望这符合您的递归标准:

def listcleaner(lst, result=None):
    if result is None:
        result = []
    if not isinstance(lst, list):
        return lst
    if not lst:
        return result
    head = listcleaner(lst[0])
    if head != []:
        result.append(head)
    return listcleaner(lst[1:], result)

测试:

>>> listcleaner([])
[]
>>> listcleaner([1, [], [2, []], 5])
[1, [2], 5]
>>> listcleaner([1, [], [2, [], [[], [], 3]], 5])
[1, [2, [3]], 5]

警告:我不知道您想对 [[[]]] 这样的嵌套案例做什么。在“删除所有空列表”的一种解释中,因为只有最里面的列表是空的,所以函数应该删除它并返回 [[]]。另一种解释是我们应该继续下去,直到没有空列表,然后返回[]。我的解决方案是后者。 (说实话,还没有找到做前者的方法……)

【讨论】:

    【解决方案3】:

    这样的?

    def listcleaner(lst): 结果 = [] 对于 lst 中的 l: 如果 type(l) == list 并且 len(l) > 0: 结果.append(listcleaner(l)) elif 类型(l)!= 列表: 结果.append(l) 返回结果

    【讨论】:

    • 不建议将type(some_object) 与类型进行比较。子类的实例仍将返回 False。您应该改用isinstance()。看我的回答。
    • 是的,但这不是递归的,我试图递归地做到这一点
    • 你看到result.append(listcleaner(l))这一行了吗?
    • 是的,很抱歉,要求说我不能使用 for 循环或 while 循环
    • 看来我们真的是同舟共济。
    【解决方案4】:
    def listcleaner(lst):
       n=len(lst)
       i=0
       while i < n :
            if isinstance(lst[i],list):
                if len(lst[i])==0:
                    del lst[i]
                    n=len(lst)
                else: 
                    listcleaner(lst[i])
                    i=i+1
            else:
                i=i+1
       return lst
    
    
    a= listcleaner([1, [], [2, []], 5])
    b= listcleaner([1,[],[2,[],[[],[],3]],5])
    print(a)
    print(b)
    

    输出:

    [1, [2], 5]
    [1, [2, [3]], 5]
    

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 2019-08-06
      • 1970-01-01
      相关资源
      最近更新 更多