Python 使用递归重新创建filter()函数

Python 使用递归重新创建filter()函数,python,recursion,Python,Recursion,我们必须使用递归重新创建filter()函数 我有以下资料: def even(X): if X % 2: return True return False def myFilter(f, L): return f(L[0]) + myFilter(f, L[1:]) 当我尝试运行:print(myFilter(偶数[0,1,2,3,4,5,6])时,我收到一个错误,提示索引器:列表索引超出范围 有人能给我指出正确的方向来解决这个问题吗 注意:我们不能

我们必须使用递归重新创建
filter()
函数

我有以下资料:

def even(X):
    if X % 2:
        return True
    return False

def myFilter(f, L):
    return f(L[0]) + myFilter(f, L[1:])
当我尝试运行:
print(myFilter(偶数[0,1,2,3,4,5,6])
时,我收到一个错误,提示
索引器:列表索引超出范围

有人能给我指出正确的方向来解决这个问题吗


注意:我们不能使用任何内置的python函数

问题是,递归最终会得到一个长度为0的列表。这就是为什么访问
L[0]
在这里不起作用的原因

def my_filter(callback, let):
     if len(lst) == 0: 
         return []
     return ([lst[0]] if callback(lst[0]) else []) + my_filter(callback, lst[1:]) 

请注意,
f(L[0])+myFilter(f,L[1:])
不起作用,因为myFilter应该返回一个列表,而f(L[0])是一个布尔值

问题是,递归最终会得到一个长度为0的列表。这就是为什么访问
L[0]
在这里不起作用的原因

def my_filter(callback, let):
     if len(lst) == 0: 
         return []
     return ([lst[0]] if callback(lst[0]) else []) + my_filter(callback, lst[1:]) 

请注意,
f(L[0])+myFilter(f,L[1:])
不起作用,因为myFilter应该返回一个列表,而f(L[0])是一个布尔值

您需要抓住基本情况:

def even(X):
    if not X % 2:
        return True
    return False

def myFilter(f, L):
    if not L:
        return []
    return [f(L[0])] + myFilter(f, L[1:])

>>> myFilter(even, [0, 1, 2, 3, 4, 5, 6])
[True, False, True, False, True, False, True]
>>> myFilter(even, [])
[]
>>> myFilter(even, [2])
[True]
>>> myFilter(even, [1])
[False]

您需要抓住基本情况:

def even(X):
    if not X % 2:
        return True
    return False

def myFilter(f, L):
    if not L:
        return []
    return [f(L[0])] + myFilter(f, L[1:])

>>> myFilter(even, [0, 1, 2, 3, 4, 5, 6])
[True, False, True, False, True, False, True]
>>> myFilter(even, [])
[]
>>> myFilter(even, [2])
[True]
>>> myFilter(even, [1])
[False]

您没有递归停止条件。试试这个:

def even(X):
    if X % 2:
        return True
    return False

def myFilter(f, L):
    if (len(L) == 1):
        return f(L[0])
    return f(L[0]) + myFilter(f, L[1:])

您没有递归停止条件。试试这个:

def even(X):
    if X % 2:
        return True
    return False

def myFilter(f, L):
    if (len(L) == 1):
        return f(L[0])
    return f(L[0]) + myFilter(f, L[1:])

您应该定义递归结束条件:

def even(X):
if X % 2:
    return True
return False


def _filter(f, l):
    if len(l) == 1:
        return [l[-1]] if f(l[-1]) else []
    else:
        return filter(f, l[:-1]) + ([l[-1]] if f(l[-1]) else [])

print(_filter(even, [1, 2, 3, 4, 5, 1, 1, 1, 6]))

您应该定义递归结束条件:

def even(X):
if X % 2:
    return True
return False


def _filter(f, l):
    if len(l) == 1:
        return [l[-1]] if f(l[-1]) else []
    else:
        return filter(f, l[:-1]) + ([l[-1]] if f(l[-1]) else [])

print(_filter(even, [1, 2, 3, 4, 5, 1, 1, 1, 6]))

其他答案正确地确定了导致异常的问题是缺乏基本案例。当使用空列表调用
myFilter
函数时,它无法访问
L[0]

但是,它们并没有解决一个事实,即您实际上根本没有进行过滤,而是执行与内置
map
函数相同的操作。如果你真的想过滤,你需要有点不同的操作

def myFilter(f, L):
    if not L:
        return []  # base case, fixes the exception

    if f(L[0]):  # use the return value of f to tell whether to include L[0] in return
        return L[0] + myFilter(f, L[1:])
    else:
        return myFilter(f, L[1:])
如果您不必使用递归,那么做同样事情的一种更具python风格(更高效)的方法是使用列表理解:

def myFilter(f, L):
    return [x for x in L if f(x)]
如果您还没有学习列表理解,那么它基本上与此解包版本相同:

def myFilter(f, L):
    result = []
    for x in L:
        if f(x):
            result.append(x)
    return result

这些版本的优点在于它们不需要显式的基本情况。如果列表
L
为空,则
for
循环将不执行任何操作,导致返回一个空列表。

其他答案已正确确定导致异常的问题是缺少基本情况。当使用空列表调用
myFilter
函数时,它无法访问
L[0]

但是,它们并没有解决一个事实,即您实际上根本没有进行过滤,而是执行与内置
map
函数相同的操作。如果你真的想过滤,你需要有点不同的操作

def myFilter(f, L):
    if not L:
        return []  # base case, fixes the exception

    if f(L[0]):  # use the return value of f to tell whether to include L[0] in return
        return L[0] + myFilter(f, L[1:])
    else:
        return myFilter(f, L[1:])
如果您不必使用递归,那么做同样事情的一种更具python风格(更高效)的方法是使用列表理解:

def myFilter(f, L):
    return [x for x in L if f(x)]
如果您还没有学习列表理解,那么它基本上与此解包版本相同:

def myFilter(f, L):
    result = []
    for x in L:
        if f(x):
            result.append(x)
    return result

这些版本的优点在于它们不需要显式的基本情况。如果列表
L
为空,则
for
循环将不执行任何操作,导致返回一个空列表。

感谢您没有使用内置函数感谢您没有使用内置函数您是否真的试图复制
过滤器
,或
映射
?也就是说,结果应该是布尔值列表(来自
偶数
函数的返回值)还是来自使
偶数
返回
的原始列表的值?除了下面的答案之外,偶数函数是向后的。。。赔率返回True,偶数返回False。您真的要复制
过滤器
,还是
映射
?也就是说,结果应该是布尔值列表(来自
偶数
函数的返回值)还是来自使
偶数
返回
的原始列表的值?除了下面的答案之外,偶数函数是向后的。。。赔率为True,偶数为False。