[英]How to find the last occurrence of an item in a Python list
Say I have this list:假设我有这个列表:
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
As far as help showed me, there is not a builtin function that returns the last occurrence of a string (like the reverse of index
).据帮助向我展示,没有返回字符串最后一次出现的内置函数(如index
的反面)。 So basically, how can I find the last occurrence of "a"
in the given list?所以基本上,我怎样才能在给定列表中找到最后一次出现的"a"
?
If you are actually using just single letters like shown in your example, then str.rindex
would work handily.如果您实际上只使用示例中所示的单个字母,那么str.rindex
将很方便。 This raises a ValueError
if there is no such item, the same error class as list.index
would raise.如果没有这样的项目,则会引发ValueError
,与list.index
将引发相同的错误类。 Demo:演示:
>>> li = ["a", "b", "a", "c", "x", "d", "a", "6"]
>>> ''.join(li).rindex('a')
6
For the more general case you could use list.index
on the reversed list:对于更一般的情况,您可以在反向列表上使用list.index
:
>>> len(li) - 1 - li[::-1].index('a')
6
The slicing here creates a copy of the entire list.此处的切片会创建整个列表的副本。 That's fine for short lists, but for the case where li
is very large, efficiency can be better with a lazy approach:这对于短列表很好,但是对于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))
One-liner version:单行版本:
next(i for i in reversed(range(len(li))) if li[i] == 'a')
A one-liner that's like Ignacio's except a little simpler/clearer would be一个类似于 Ignacio 的单线,除了更简单/更清晰一点是
max(loc for loc, val in enumerate(li) if val == 'a')
It seems very clear and Pythonic to me: you're looking for the highest index that contains a matching value.对我来说,这似乎非常清晰和 Pythonic:您正在寻找包含匹配值的最高索引。 No nexts, lambdas, reverseds or itertools required.不需要 nexts、lambdas、reverses 或 itertools。
Many of the other solutions require iterating over the entire list.许多其他解决方案需要遍历整个列表。 This does not.这没有。
def find_last(lst, elm):
gen = (len(lst) - 1 - i for i, v in enumerate(reversed(lst)) if v == elm)
return next(gen, None)
Edit: In hindsight this seems like unnecessary wizardry.编辑:事后看来,这似乎是不必要的巫术。 I'd do something like this instead:我会做这样的事情:
def find_last(lst, sought_elt):
for r_idx, elt in enumerate(reversed(lst)):
if elt == sought_elt:
return len(lst) - 1 - r_idx
>>> (x for x in reversed(list(enumerate(li))) if x[1] == 'a').next()[0]
6
>>> len(li) - (x for x in enumerate(li[::-1]) if x[1] == 'a').next()[0] - 1
6
I like both wim's and Ignacio's answers.我喜欢wim和Ignacio 的答案。 However, I think itertools
provides a slightly more readable alternative, lambda notwithstanding.但是,我认为itertools
提供了一个更易读的替代方案,尽管有 lambda。 (For Python 3; for Python 2, use xrange
instead of range
). (对于 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
This will raise a StopIteration
exception if the item isn't found;如果未找到该项目,这将引发StopIteration
异常; you could catch that and raise a ValueError
instead, to make this behave just like index
.您可以抓住它并引发ValueError
,以使其表现得像index
。
Defined as a function, avoiding the lambda
shortcut:定义为函数,避免使用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")
It works for non-chars too.它也适用于非字符。 Tested:测试:
>>> rindex(['apples', 'oranges', 'bananas', 'apples'], 'apples')
3
dict
用dict
You can use the fact that dictionary keys are unique and when building one with tuples only the last assignment of a value for a particular key will be used.您可以使用字典键是唯一的这一事实,并且在使用元组构建一个时,只会使用特定键的最后一个值分配。 As stated in other answers, this is fine for small lists but it creates a dictionary for all unique values and might not be efficient for large lists.如其他答案所述,这对于小列表很好,但它为所有唯一值创建一个字典,对于大列表可能效率不高。
dict(map(reversed, enumerate(li)))["a"]
6
I came here hoping to find someone had already done the work of writing the most efficient version of list.rindex
, which provided the full interface of list.index
(including optional start
and stop
parameters).我来到这里是希望找到有人已经完成了编写最有效版本的list.rindex
的工作,它提供了list.index
的完整接口(包括可选的start
和stop
参数)。 I didn't find that in the answers to this question, or here , or here , or here .我没有在这个问题的答案中找到,或者在这里,或者这里,或者这里。 So I put this together myself... making use of suggestions from other answers to this and the other questions.所以我自己把它放在一起......利用其他答案和其他问题的建议。
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)
The technique using len(seq) - 1 - next(i for i,v in enumerate(reversed(seq)) if v == value)
, suggested in several other answers, can be more space-efficient: it needn't create a reversed copy of the full list.在其他几个答案中建议使用len(seq) - 1 - next(i for i,v in enumerate(reversed(seq)) if v == value)
的技术可以更节省空间:它不需要创建完整列表的反向副本。 But in my (offhand, casual) testing, it's about 50% slower.但在我的(临时的、随意的)测试中,它慢了大约 50%。
last_occurence=len(yourlist)-yourlist[::-1].index(element)-1
就这么简单。无需导入或创建函数。
lastIndexOf = lambda array, item: len(array) - (array[::-1].index(item)) - 1
Love @alcalde's solution, but faced ValueError: max() arg is an empty sequence if none of the elements match the condition.喜欢@alcalde 的解决方案,但面临ValueError: max() arg is an empty sequence如果没有任何元素符合条件。
To avoid the error set default=None :为避免错误设置default=None :
max((loc for loc, val in enumerate(li) if val == 'a'), default=None)
Use a simple loop:使用一个简单的循环:
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))
如果列表很小,您可以计算所有索引并返回最大的:
index = max(i for i, x in enumerate(elements) if x == 'foo')
Here is a function for finding the last occurrence of an element in a list.这是一个用于查找列表中元素的最后一次出现的函数。 A list and an element are passed to the function.一个列表和一个元素被传递给函数。
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")
Inside the last_occurrence
function a for
loop is used with range
.在last_occurrence
函数内部, for
循环与range
一起使用。 which will iterate the list in reverse order.这将以相反的顺序迭代列表。 if the element of the current index match the searched
element, the function will return the index
.如果当前索引的元素与searched
到的元素匹配,该函数将返回index
。 In case after comparing all elements in the list the searched
element is not found function will return -1
.如果在比较列表中的所有元素后未找到searched
的元素,函数将返回-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))
val = [1,2,2,2,2,2,4,5]. val = [1,2,2,2,2,2,4,5]。
If you need to find last occurence of 2如果您需要查找 2 的最后一次出现
last_occurence = (len(val) -1) - list(reversed(val)).index(2)
from array import array
fooa = array('i', [1,2,3])
fooa.reverse() # [3,2,1]
fooa.index(1)
>>> 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.