95

假设我有这个列表:

li = ["a", "b", "a", "c", "x", "d", "a", "6"]

据帮助向我展示,没有返回字符串最后一次出现的内置函数(如 的反面index)。所以基本上,我怎样才能找到"a"给定列表中的最后一次出现?

4

16 回答 16

109

如果您实际上只使用示例中所示的单个字母,那么str.rindex会很方便。ValueError如果没有这样的项目,这将引发一个与list.index将引发的相同错误类。演示:

>>> li = ["a", "b", "a", "c", "x", "d", "a", "6"]
>>> ''.join(li).rindex('a')
6

对于更一般的情况,您可以list.index在反向列表中使用:

>>> len(li) - 1 - li[::-1].index('a')
6

此处的切片会创建整个列表的副本。这对于短列表很好,但是对于li非常大的情况,使用惰性方法可以提高效率:

def list_rindex(li, x):
    for i in reversed(range(len(li))):
        if li[i] == x:
            return i
    raise ValueError("{} is not in list".format(x))

单行版本:

next(i for i in reversed(range(len(li))) if li[i] == 'a')
于 2011-07-31T15:12:51.850 回答
50

一个类似于 Ignacio 的单线,除了更简单/更清晰一点是

max(loc for loc, val in enumerate(li) if val == 'a')

对我来说,这似乎非常清晰和 Pythonic:您正在寻找包含匹配值的最高索引。不需要 nexts、lambdas、reverses 或 itertools。

于 2014-05-22T20:04:47.743 回答
18

许多其他解决方案需要遍历整个列表。这没有。

def find_last(lst, elm):
  gen = (len(lst) - 1 - i for i, v in enumerate(reversed(lst)) if v == elm)
  return next(gen, None)

编辑:事后看来,这似乎是不必要的巫术。我会做这样的事情:

def find_last(lst, sought_elt):
    for r_idx, elt in enumerate(reversed(lst)):
        if elt == sought_elt:
            return len(lst) - 1 - r_idx
于 2014-04-18T01:39:56.717 回答
8
>>> (x for x in reversed([y for y in enumerate(li)]) if x[1] == 'a').next()[0]
6

>>> len(li) - (x for x in (y for y in enumerate(li[::-1])) if x[1] == 'a').next()[0] - 1
6
于 2011-07-31T15:02:03.327 回答
7

我喜欢wimIgnacio 的答案。然而,我认为itertools提供了一个更易读的替代方案,尽管有 lambda。(对于 Python 3;对于 Python 2,使用xrange代替range)。

>>> from itertools import dropwhile
>>> l = list('apples')
>>> l.index('p')
1
>>> next(dropwhile(lambda x: l[x] != 'p', reversed(range(len(l)))))
2

StopIteration如果找不到该项目,这将引发异常;您可以抓住它并提出 a ValueError,以使其表现得像index.

定义为函数,避免使用lambda快捷方式:

def rindex(lst, item):
    def index_ne(x):
        return lst[x] != item
    try:
        return next(dropwhile(index_ne, reversed(range(len(lst)))))
    except StopIteration:
        raise ValueError("rindex(lst, item): item not in list")

它也适用于非字符。测试:

>>> rindex(['apples', 'oranges', 'bananas', 'apples'], 'apples')
3
于 2011-07-31T20:27:03.287 回答
5

dict

您可以使用字典键是唯一的这一事实,并且在使用元组构建一个时,只会使用特定键的最后一个值分配。如其他答案所述,这对于小列表很好,但它为所有唯一值创建一个字典,对于大列表可能效率不高。

dict(map(reversed, enumerate(li)))["a"]

6
于 2018-06-11T16:04:37.940 回答
2

我来到这里是希望找到有人已经完成了编写最有效版本的工作list.rindex,它提供了完整的接口list.index(包括可选startstop参数)。我没有在这个问题的答案中找到,或者在这里,或者这里,或者这里。所以我自己把它放在一起......利用其他答案和其他问题的建议。

def rindex(seq, value, start=None, stop=None):
  """L.rindex(value, [start, [stop]]) -> integer -- return last index of value.
  Raises ValueError if the value is not present."""
  start, stop, _ = slice(start, stop).indices(len(seq))
  if stop == 0:
    # start = 0
    raise ValueError('{!r} is not in list'.format(value))
  else:
    stop -= 1
    start = None if start == 0 else start - 1
  return stop - seq[stop:start:-1].index(value)

在其他几个答案中建议的使用技术len(seq) - 1 - next(i for i,v in enumerate(reversed(seq)) if v == value)可以更节省空间:它不需要创建完整列表的反向副本。但在我的(临时的、随意的)测试中,它慢了大约 50%。

于 2017-06-26T18:13:47.450 回答
1
last_occurence=len(yourlist)-yourlist[::-1].index(element)-1

就这么简单。无需导入或创建函数。

于 2018-04-13T10:09:14.940 回答
0

使用一个简单的循环:

def reversed_index(items, value):
    for pos, curr in enumerate(reversed(items)):
        if curr == value:
            return len(items) - pos - 1
    raise ValueError("{0!r} is not in list".format(value))
于 2015-06-19T14:07:45.603 回答
0

这是一个用于查找列表中元素的最后一次出现的函数。一个列表和一个元素被传递给函数。

li = ["a", "b", "a", "c", "x", "d", "a", "6"]
element = "a"

def last_occurrence(li,element):
    for i in range(len(li)-1,0,-1):
        if li[i] == element:
            return i

    return -1

last_occ = last_occurrence(li, element)
if (last_occ != -1):
    print("The last occurrence at index : ",last_occ)
else:
    print("Element not found")

last_occurrence函数内部,for循环与range. 这将以相反的顺序迭代列表。如果当前索引的元素与该searched元素匹配,该函数将返回index. 如果在比较列表中的所有元素后searched未找到元素,函数将返回-1

于 2021-12-16T09:01:37.117 回答
0

喜欢@alcalde 的解决方案,但面临ValueError: max() arg is an empty sequence如果没有任何元素符合条件。

为避免错误设置default=None

max((loc for loc, val in enumerate(li) if val == 'a'), default=None)
于 2022-02-01T11:08:20.697 回答
0

如果列表很小,您可以计算所有索引并返回最大的:

index = max(i for i, x in enumerate(elements) if x == 'foo')
于 2020-12-05T01:19:18.263 回答
0
lastIndexOf = lambda array, item: len(array) - (array[::-1].index(item)) - 1
于 2020-02-25T21:10:06.840 回答
-1

enumerate这是获取最后一个索引,使用和列表理解的一个小单行:

li = ["a", "b", "a", "c", "x", "d", "a", "6"]
[l[0] for l in enumerate(li) if l[1] == "a"][-1]
于 2018-01-04T16:21:21.837 回答
-1
def rindex(lst, val):
    try:
        return next(len(lst)-i for i, e in enumerate(reversed(lst), start=1) if e == val)
    except StopIteration:
        raise ValueError('{} is not in list'.format(val))
于 2016-08-30T02:57:28.133 回答
-1

val = [1,2,2,2,2,2,4,5]。

如果您需要查找 2 的最后一次出现

last_occurence = (len(val) -1) - list(reversed(val)).index(2)

于 2017-09-24T11:06:13.710 回答