使用递归从列表中删除值

时间:2018-11-12 15:27:48

标签: python recursion

我已经定义了一个包含两个参数的递归函数delete()

  • lst:类型为list
  • to_delete:需要从列表中删除的值

但是,我使用了函数del(),这是我们尚未了解的功能。因此,我想知道是否存在一种不使用功能del()

的更简单的方法来输出相同的解决方案

这是我的代码:

def delete(lst, to_delete):
    """
    parameters : lst of type list
                 to_delete : represents a value one wants to delete from the list
    returns : another list with the same elements minus the ones one asks to delete
    """
    if not lst:
        return []
    else:
        if lst[0] == to_delete:
            del lst[0]
            return delete(lst[1:], to_delete)
        return [lst[0]] + delete(lst[1:], to_delete)

print(delete([1,2,3,4,5,5,6,5,7,5], 5))

输出:

> [1,2,3,4,6]       #where is 7 ?

4 个答案:

答案 0 :(得分:0)

  • 缺少7个,因为即使您刚刚delete(lst[1:], to_delete)遇到了del,您仍然返回lst[0]:您应该在此处使用delete(lst[0:], to_delete)
  • 另一种选择是 not 代替del的第0个元素,而 just 返回delete(lst[1:], to_delete)
  • 除了递归地执行此操作外,您还可以使用列表推导:

def delete(lst, to_delete):
    return [element for element in lst if element != to_delete]

答案 1 :(得分:0)

使用递归

即使使用递归,也不需要使用del

def delete(lst, to_delete):
    """
    parameters : lst of type list
                to_delete : represents a value one wants to delete from the list
    returns : another list with the same elements minus the ones one asks to delete
    """
    if not lst:
        return []
    if lst[0] == to_delete:
        return delete(lst[1:], to_delete)
    return [lst[0]] + delete(lst[1:], to_delete)

如您所见,您在重复自己一点(delete(lst[1:], to_delete)被使用了两次),因此您可以将其缩短为:

def delete(lst, to_delete):
    """
    parameters : lst of type list
                to_delete : represents a value one wants to delete from the list
    returns : another list with the same elements minus the ones one asks to delete
    """
    if not lst:
        return []
    start = [] if lst[0] == to_delete else [lst[0]]
    return start + delete(lst[1:], to_delete)

虽然我不知道它的性能。

无递归

如果您不需要使用递归,则可以使用列表推导来获得更少的代码:

def delete(lst, to_delete):
    return [x for x in lst if x != to_delete]

如果您不太了解列表推导,从逻辑上讲,它等效于以下内容:

def delete(lst, to_delete):
    res = []
    for x in lst:
        if x != to_delete:
            res.append(x)
    return res

编辑:我错过了,但是在输出中看不到7的原因是,del lst[0]已经从列表中删除了第一个值,因此,则缺少列表的“新”第一个值。

答案 2 :(得分:0)

您似乎对递归感兴趣。递归是一种功能性遗产,因此,我将带您一窥关于该问题的功能性观点。下面,deletefilter的特化,它是reduce的特化,一种简单的递归形式-

def reduce (f, state = None, xs = [], i = 0):
  if i >= len (xs):
    return state
  else:
    return reduce \
      ( f
      , f (state, xs[i], i)
      , xs
      , i + 1
      )

def filter (f, xs = []):
  return reduce \
    ( lambda acc, x, i:
        acc + [x] if f (x) else acc
    , []
    , xs
    )

def delete (q, xs = []):
  return filter \
    ( lambda x: q != x
    , xs
    )

print (delete (5, [ 1, 2, 5, 3, 5, 5, 2, 3, 1, 5, 1 ]))
# [1, 2, 3, 2, 3, 1, 1]

print (delete ('x', 'abxcdxefxghxi'))
# ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

功能样式不是Python的惯用样式。但是,那些希望在Python中探索功能风格的人并没有被完全忽略。您可以在Python的functools模块中找到reducefilter(还有许多其他有用的函数)。

这里reducefilter的定义是我自己的。如果您使用functools,则需要更仔细地阅读特定行为。

答案 3 :(得分:-1)

重新创建您的列表而无需不需要的项目会更简单:

def delete(lst, to_delete):
    return [x for x in lst if x!=to_delete]

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

更正您的代码(但保留递归)看起来像这样:

def delete(lst, to_delete):
    """
    parameters : lst of type list
                 to_delete : represents a value one wants to delete from the list
    returns : another list with the same elements minus the ones one asks to delete
    """
    if not lst:
        return []
    else:
        res = []
        for item in lst:
            if item == to_delete:
                continue
            else:
                res.append(item)
        return res

具有相同的结果。


最后,我强烈反对此应用程序的递归选项如下:

def delete(lst, to_delete, res=[]):
    """
    parameters : lst of type list
                 to_delete : represents a value one wants to delete from the list
    returns : another list with the same elements minus the ones one asks to delete
    """
    if not lst:
        return res
    else:
        item = lst[0]
        if item != to_delete:
            res.append(item)
        return delete(lst[1:], to_delete, res=res)