如何在Python列表中查找项的最后一次出现

时间:2011-07-31 14:58:34

标签: python list last-occurrence

说我有这个清单:

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

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

15 个答案:

答案 0 :(得分:73)

如果您实际上只使用了示例中显示的单个字母,那么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')

答案 1 :(得分:29)

像Ignacio这样的单线,除了更简单/更清晰之外

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

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

答案 2 :(得分:15)

许多其他解决方案需要迭代整个列表。这不是。

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

答案 3 :(得分:7)

我喜欢wim'sIgnacio's个答案。但是,我认为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异常;你可以抓住它并提出一个ValueError,使其表现得just like 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

答案 4 :(得分:6)

>>> (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

答案 5 :(得分:4)

使用dict

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

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

6

答案 6 :(得分:2)

我来到这里希望找到某人已经完成编写list.rindex最有效版本的工作,该版本提供了list.index的完整界面(包括可选start和{{ 1}}参数)。我在这个问题的答案中找不到,或hereherehere。所以我自己把它放在一起......利用其他问题的建议以及其他问题。

stop

在其他几个答案中提到的使用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) 的技术可以更节省空间:它不需要创建完整列表的反向副本。但在我的(随意,随意)测试中,它的速度要慢50%。

答案 7 :(得分: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))

答案 8 :(得分:0)

last_occurence=len(yourlist)-yourlist[::-1].index(element)-1

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

答案 9 :(得分:0)

lastIndexOf = lambda array, item: len(array) - (array[::-1].index(item)) - 1

答案 10 :(得分:0)

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

index = max(i for i, x in enumerate(elements) if x == 'foo')

答案 11 :(得分:-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))

答案 12 :(得分:-1)

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

如果你需要找到2的最后一次出现

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

答案 13 :(得分:-1)

使用enumerate和列表理解,这里有一个用于获取最后一个索引的小内容:

li = ["a", "b", "a", "c", "x", "d", "a", "6"]
[l[0] for l in enumerate(li) if l[1] == "a"][-1]

答案 14 :(得分:-2)

from array import array
fooa = array('i', [1,2,3])
fooa.reverse()  # [3,2,1]
fooa.index(1)
>>> 2