Python 如何返回列表的最后一个索引

Python 如何返回列表的最后一个索引,python,recursion,indexing,Python,Recursion,Indexing,可能重复: 嗨,我想知道是否有人能帮我学习Python。我试图创建一个代码,以递归方式返回列表中最后一次出现的项的最后一个索引。所以在列表[1,2,3,4,5,2]中,最后一个应该返回4。它只接受两个变量,即列表和它正在搜索的项。如果未找到任何匹配变量,则返回-1 到目前为止,我有: def lstIndex(lst, item): if len(lst) == 0: return -1 place = lst[0] if place == item:

可能重复:

嗨,我想知道是否有人能帮我学习Python。我试图创建一个代码,以递归方式返回列表中最后一次出现的项的最后一个索引。所以在列表[1,2,3,4,5,2]中,最后一个应该返回4。它只接受两个变量,即列表和它正在搜索的项。如果未找到任何匹配变量,则返回-1

到目前为止,我有:

def lstIndex(lst, item):
    if len(lst) == 0:
        return -1
    place = lst[0]
    if place == item:
        print(place)
        #just return the index
        return lst.index(place)
    else:
        return lstIndex(lst[1:],item)

如果不需要递归,可以使用以下方法:

def find_last(lst,item):
    try:
       return len(lst) - next(i for i,elem in enumerate(reversed(lst),1) if elem == item)
    except StopIteration:
       return -1


a = [1,2,3,4,5,4,3]
idx = find_last(a,4)
print a[idx]
print find_last(a,6)

如果不需要递归,可以使用以下方法:

def find_last(lst,item):
    try:
       return len(lst) - next(i for i,elem in enumerate(reversed(lst),1) if elem == item)
    except StopIteration:
       return -1


a = [1,2,3,4,5,4,3]
idx = find_last(a,4)
print a[idx]
print find_last(a,6)

短迭代解:

try:
    return (len(lst)-1) - lst[::-1].index(item)
except ValueError:
    return -1
但是,由于您正在显式地寻找递归解决方案,因此我将向您展示如何递归地完成它。但是,它不会有效率;如果你想要一个好的,高效的,Pythonic的解决方案,你应该使用一个迭代的解决方案,就像其他人已经展示的或者上面的一样

实际上有几种方法可以做到这一点。您可以使用一个helper函数,它接受一个额外的参数,指定找到该值的最后一个索引:

def list_rfind(lst, item):
    def list_rfind_helper(i, item, last=-1):
        if i >= len(lst): return last
        if lst[i] == item: last = i
        return list_rfind_helper(i+1, item, last)

    return list_rfind_helper(0, item)
您可以在没有辅助功能的情况下执行此操作:

def list_rfind(lst, item):
    if not lst:
        return -1

    res = list_rfind(lst[1:], item)
    if res >= 0:
        return res+1
    elif lst[0] == item:
        return 0
    else:
        return -1

短迭代解:

try:
    return (len(lst)-1) - lst[::-1].index(item)
except ValueError:
    return -1
但是,由于您正在显式地寻找递归解决方案,因此我将向您展示如何递归地完成它。但是,它不会有效率;如果你想要一个好的,高效的,Pythonic的解决方案,你应该使用一个迭代的解决方案,就像其他人已经展示的或者上面的一样

实际上有几种方法可以做到这一点。您可以使用一个helper函数,它接受一个额外的参数,指定找到该值的最后一个索引:

def list_rfind(lst, item):
    def list_rfind_helper(i, item, last=-1):
        if i >= len(lst): return last
        if lst[i] == item: last = i
        return list_rfind_helper(i+1, item, last)

    return list_rfind_helper(0, item)
您可以在没有辅助功能的情况下执行此操作:

def list_rfind(lst, item):
    if not lst:
        return -1

    res = list_rfind(lst[1:], item)
    if res >= 0:
        return res+1
    elif lst[0] == item:
        return 0
    else:
        return -1
为了完整起见:

def list_rfind(lst, item):
    return (len(lst)-1) - sum(1 for _ in iter(reversed(lst).next, item))
为了完整起见:

def list_rfind(lst, item):
    return (len(lst)-1) - sum(1 for _ in iter(reversed(lst).next, item))

我不是100%确定我知道你想要什么。你的陈述是。。。在[1,2,3,4,5,2]的列表中,最后一个应返回4。。。让我有点困惑;我认为您希望返回指定项最后一次出现的索引。因此,要使4成为指定列表中的结果,项必须是5

正如其他地方所指出的,递归函数在这里不是最有效或最符合Python的解决方案。我更喜欢一个类似于中第一个的解决方案

但是,如果它必须是递归的,我相信下面的代码可以满足您的需要。在递归调用中传递列表时,需要使用[:-1]作为索引范围,而不是使用[1:]从前面单步遍历列表:

def lstIndex(lst, item):
    if len(lst) == 0:
        return -1
    elif lst[-1] == item:
        return len(lst) - 1
    else:
        return lstIndex(lst[0:-1], item)
我用以下方法进行了测试:

the_list = [1,2,3,4,5,2]
print lstIndex(the_list, 2)
print lstIndex(the_list, 1)
print lstIndex(the_list, 3)
print lstIndex(the_list, 4)
print lstIndex(the_list, 5)
print lstIndex(the_list, 6)
print lstIndex(the_list, 0)
具有以下输出:

五, 0 2. 3. 4. -1 -一,


我不是100%确定我知道你想要什么。你的陈述是。。。在[1,2,3,4,5,2]的列表中,最后一个应返回4。。。让我有点困惑;我认为您希望返回指定项最后一次出现的索引。因此,要使4成为指定列表中的结果,项必须是5

正如其他地方所指出的,递归函数在这里不是最有效或最符合Python的解决方案。我更喜欢一个类似于中第一个的解决方案

但是,如果它必须是递归的,我相信下面的代码可以满足您的需要。在递归调用中传递列表时,需要使用[:-1]作为索引范围,而不是使用[1:]从前面单步遍历列表:

def lstIndex(lst, item):
    if len(lst) == 0:
        return -1
    elif lst[-1] == item:
        return len(lst) - 1
    else:
        return lstIndex(lst[0:-1], item)
我用以下方法进行了测试:

the_list = [1,2,3,4,5,2]
print lstIndex(the_list, 2)
print lstIndex(the_list, 1)
print lstIndex(the_list, 3)
print lstIndex(the_list, 4)
print lstIndex(the_list, 5)
print lstIndex(the_list, 6)
print lstIndex(the_list, 0)
具有以下输出:

五, 0 2. 3. 4. -1 -一,


是否需要递归?您可能希望看到以下问题:您可以反向转换列表,并返回第一个索引。为什么要请求递归解决方案,然后选择非递归解决方案作为最佳解决方案?诚然,这是一个更好的方法,但如果这是可以接受的,那么你最好避免说你想要一个递归的解决方案。@brian Chiem:虽然我很感激把选择的答案换成我的答案,但这不是我之前评论的重点或愿望。我只是说我觉得你最好保持一致。如果你意识到另一种方法更好,我建议你编辑你的答案或留下评论来解释情况。我不想在这里提出批评抱歉,如果这样的话,我只想选择与他们的问题一致的答案——或者对不一致性有一个解释;否则,我担心未来的观众会被这种不一致性搞糊涂。它需要递归吗?你可能会想看到这样一个问题:你可以反向转换列表,然后返回第一个索引。你为什么要求递归解决方案,然后选择非递归的答案作为最佳答案?诚然,这是一个更好的方法,但如果这是可以接受的,那么你最好避免说你想要一个递归的解决方案。@brian Chiem:虽然我很感激把选择的答案换成我的答案,但这不是我之前评论的重点或愿望。我只是说我觉得你最好保持一致。如果你意识到另一种方法更好,我建议你编辑你的答案或者离开

一个解释这种情况的评论。我不想在这里提出批评抱歉,如果这样的话,我只想选择与他们的问题一致的答案——或者对不一致性有一个解释;否则,我担心未来的观众会被这种不一致性搞糊涂。我认为你想要lenlst-I+1,因为[lena]每次都会给你一个索引器。@mgilson。。是的,没错。编辑代码:而且,我想您可能应该在最后返回-1,以满足OP的规范。但除此之外,我们发布了几乎相同的代码。齐了。@mgilson。谢谢:再次编辑。你们知道当列表的索引等于项目时如何返回它吗?我想你们需要lenlst-I+1,因为[lena]每次都会给你们一个索引器。@mgilson。。是的,没错。编辑代码:而且,我想您可能应该在最后返回-1,以满足OP的规范。但除此之外,我们发布了几乎相同的代码。齐了。@mgilson。谢谢:再次编辑。你们知道当列表的索引等于项目时如何返回吗?+1用于使用生成器。你的更好@RohitJain-出于某种原因,每当我想要序列的第一个元素受某种条件约束时,我都会在seq if condition中找到nextitem。。。这只是习惯。@mgilson。。我认为这要好得多。嗯,我还需要养成习惯。使代码变得如此干净:@RohitJain-很快它显示我的代码是这里最慢的。我并不认为它总是更好。@mgilson:在我看来,实际上更好,但你是对的,递归不是必需的。我不想对这个答案投赞成票,但你的答案可能会更有记忆效率,再加上你在评论中给了我们一些自我批评+1+1用于使用发电机。你的更好@RohitJain-出于某种原因,每当我想要序列的第一个元素受某种条件约束时,我都会在seq if condition中找到nextitem。。。这只是习惯。@mgilson。。我认为这要好得多。嗯,我还需要养成习惯。使代码变得如此干净:@RohitJain-很快它显示我的代码是这里最慢的。我并不认为它总是更好。@mgilson:在我看来,实际上更好,但你是对的,递归不是必需的。我不想对这个答案投赞成票,但你的答案可能会更有记忆效率,再加上你在评论中给了我们一些自我批评+1你不想要lenlst-lst[:-1].indexitem+1吗?是的,我的错。谢谢你接电话,没问题。很乐意帮忙:。我想知道我们的各种答案在效率方面如何比较…正如我所预期的,在我建立的一个非常简化的基准中,你的答案是最快的。这是最好的解决方案第一个,没有递归,但是由于递归是OP所要求的,而且你也给出了这样的选项,那么我认为这个答案是最好的。你不想要lenlst-lst[:-1].indexitem+1?是的,我的错。谢谢你接电话,没问题。很乐意帮忙:。我想知道我们的各种答案在效率方面如何比较……正如我所预期的,在我建立的一个非常简化的基准中,你的答案是最快的。这是最好的解决方案第一个,没有递归,但由于递归是OP所要求的,而且你也给出了这样的选项,那么这个答案在我看来是最好的。@nneonneo。。那么你在上一个答案中发布了一个不完整的代码??英雄联盟最后一个不是不完整的,这只是我的高尔夫代码条目嗯,是的,我看这一个更好更干净+1:啊,在这儿。世界又好了。我应该指出,我真的不喜欢这个解决方案。它太聪明了,因为它在一个月的时间内不会很容易阅读,而且它恰好是迄今为止发布的四个迭代解决方案中速度最慢的。我想这也是一个很好的理由,可以把它放在一个单独的答案中。@nneonneo。。那么你在上一个答案中发布了一个不完整的代码??英雄联盟最后一个不是不完整的,这只是我的高尔夫代码条目嗯,是的,我看这一个更好更干净+1:啊,在这儿。世界又好了。我应该指出,我真的不喜欢这个解决方案。它太聪明了,因为它在一个月的时间内不会很容易阅读,而且它恰好是迄今为止发布的四个迭代解决方案中速度最慢的。我想这也是一个很好的理由,可以把它归入一个单独的答案。