[英]How to find the last occurrence of an item in a Python list
假設我有這個列表:
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
據幫助向我展示,沒有返回字符串最后一次出現的內置函數(如index
的反面)。 所以基本上,我怎樣才能在給定列表中找到最后一次出現的"a"
?
如果您實際上只使用示例中所示的單個字母,那么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')
一個類似於 Ignacio 的單線,除了更簡單/更清晰一點是
max(loc for loc, val in enumerate(li) if val == 'a')
對我來說,這似乎非常清晰和 Pythonic:您正在尋找包含匹配值的最高索引。 不需要 nexts、lambdas、reverses 或 itertools。
許多其他解決方案需要遍歷整個列表。 這沒有。
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
>>> (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
我喜歡wim和Ignacio 的答案。 但是,我認為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
,以使其表現得像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
dict
您可以使用字典鍵是唯一的這一事實,並且在使用元組構建一個時,只會使用特定鍵的最后一個值分配。 如其他答案所述,這對於小列表很好,但它為所有唯一值創建一個字典,對於大列表可能效率不高。
dict(map(reversed, enumerate(li)))["a"]
6
我來到這里是希望找到有人已經完成了編寫最有效版本的list.rindex
的工作,它提供了list.index
的完整接口(包括可選的start
和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)
在其他幾個答案中建議使用len(seq) - 1 - next(i for i,v in enumerate(reversed(seq)) if v == value)
的技術可以更節省空間:它不需要創建完整列表的反向副本。 但在我的(臨時的、隨意的)測試中,它慢了大約 50%。
last_occurence=len(yourlist)-yourlist[::-1].index(element)-1
就這么簡單。無需導入或創建函數。
lastIndexOf = lambda array, item: len(array) - (array[::-1].index(item)) - 1
喜歡@alcalde 的解決方案,但面臨ValueError: max() arg is an empty sequence如果沒有任何元素符合條件。
為避免錯誤設置default=None :
max((loc for loc, val in enumerate(li) if val == 'a'), default=None)
使用一個簡單的循環:
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')
這是一個用於查找列表中元素的最后一次出現的函數。 一個列表和一個元素被傳遞給函數。
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
。
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]。
如果您需要查找 2 的最后一次出現
last_occurence = (len(val) -1) - list(reversed(val)).index(2)
這是使用enumerate
和列表理解獲取最后一個索引的小單行:
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
[l[0] for l in enumerate(li) if l[1] == "a"][-1]
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.