[英]Finding first and last index of some value in a list in Python
是否有任何内置方法是列表的一部分,可以给我某个值的第一个和最后一个索引,例如:
verts.IndexOf(12.345)
verts.LastIndexOf(12.345)
序列有一个方法index(value)
,它返回第一次出现的索引 - 在你的情况下这将是verts.index(value)
。
您可以在verts[::-1]
上运行它以找出最后一个索引。 在这里,这将是len(verts) - 1 - verts[::-1].index(value)
如果您要搜索mylist
最后一次出现的myvalue
的索引:
len(mylist) - mylist[::-1].index(myvalue) - 1
使用i1 = yourlist.index(yourvalue)
和i2 = yourlist.rindex(yourvalue).
我对我的这个错误答案一直感到不高兴,但这似乎是人们正在寻找的东西。 这里是找到的最后一个索引的解决方案i
你的价值的12.345
您的列表verts
。
for i, v in enumerate(reversed(verts)):
if v == '12.345':
break
也许找到最后一个索引的两种最有效的方法:
def rindex(lst, value):
lst.reverse()
i = lst.index(value)
lst.reverse()
return len(lst) - i - 1
def rindex(lst, value):
return len(lst) - operator.indexOf(reversed(lst), value) - 1
两者都只占用 O(1) 额外空间,并且第一个解决方案的两个就地反转比创建反向副本快得多。 让我们将其与之前发布的其他解决方案进行比较:
def rindex(lst, value):
return len(lst) - lst[::-1].index(value) - 1
def rindex(lst, value):
return len(lst) - next(i for i, val in enumerate(reversed(lst)) if val == value) - 1
这是用于在包含一百万个数字的列表中搜索一个数字。 x 轴是搜索元素的位置:0% 表示它在列表的开头,100% 表示它在列表的末尾。 所有解决方案都在 100% 位置最快,两个reversed
解决方案几乎不需要时间,双反向解决方案需要一点时间,而反向复制需要很多时间。
在位置 100% 处,反向复制解决方案和双反向解决方案将所有时间都花在反转上( index()
是即时的),因此我们看到两个就地反转的速度大约是创建反转的 7 倍反向复制。
上面是lst = list(range(1_000_000, 2_000_001))
,它几乎在内存中按顺序创建 int 对象,这对缓存非常友好。 让我们在用random.shuffle(lst)
列表之后再做一次(可能不太现实,但很有趣):
正如预期的那样,一切都变慢了。 反向复制解决方案受到的影响最大,在 100% 时,它现在需要大约双反向解决方案的 32 倍(!)。 enumerate
解决方案现在仅次于位置 98% 是第二快的。
总的来说,我最喜欢operator.indexOf
解决方案,因为它是所有位置的后一半或四分之一速度最快的解决方案,如果您实际上正在为某事做rindex
,这可能是更有趣的位置。 它只比早期位置的双反向解决方案慢一点。
在 Windows 10 Pro 1903 64 位上使用 CPython 3.9.0 64 位完成的所有基准测试。
作为一个小辅助函数:
def rindex(mylist, myvalue):
return len(mylist) - mylist[::-1].index(myvalue) - 1
Python 列表具有index()
方法,您可以使用它来查找列表中某项第一次出现的位置。 请注意,当列表中不存在该项目时, list.index()
会引发ValueError
,因此您可能需要将其包装在try
/ except
:
try:
idx = lst.index(value)
except ValueError:
idx = None
要有效地查找列表中项目最后一次出现的位置(即不创建反向中间列表),您可以使用此函数:
def rindex(lst, value):
for i, v in enumerate(reversed(lst)):
if v == value:
return len(lst) - i - 1 # return the index in the original list
return None
print(rindex([1, 2, 3], 3)) # 2
print(rindex([3, 2, 1, 3], 3)) # 3
print(rindex([3, 2, 1, 3], 4)) # None
正确的解决方案是执行“C 级反向循环匹配”的解决方案。
在伪 C 代码中:
for (int i = len(list) -1; i >= 0; i--)
if list[i] == value:
return i
raise NotFound
在Python中,正确的解法应该是:
def rindex(lst, value):
# reversed is a buitin backward iterator
# operator.indexOf can handle this iterator
# if value is not Found it raises
# ValueError: sequence.index(x): x not in sequence
_ = operator.indexOf(reversed(lst), value)
# we must fix the resersed index
return len(lst) - _ - 1
但是内置一个反向索引会更好。
这个方法可以比上面更优化
def rindex(iterable, value):
try:
return len(iterable) - next(i for i, val in enumerate(reversed(iterable)) if val == value) - 1
except StopIteration:
raise ValueError
s.index(x[, i[, j]])
x 在 s 中首次出现的索引(在索引 i 处或之后和索引 j 之前)
使用max
+ enumerate
获取最后一个元素出现
rindex = max(i for i, v in enumerate(your_list) if v == your_value)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.