Each Answer to this Q is separated by one/two green lines.

Is there any built-in methods that are part of lists that would give me the first and last index of some value, like:

```
verts.IndexOf(12.345)
verts.LastIndexOf(12.345)
```

Sequences have a method `index(value)`

which returns index of first occurrence – in your case this would be `verts.index(value)`

.

You can run it on `verts[::-1]`

to find out the last index. Here, this would be `len(verts) - 1 - verts[::-1].index(value)`

If you are searching for the index of the last occurrence of `myvalue`

in `mylist`

:

```
len(mylist) - mylist[::-1].index(myvalue) - 1
```

Perhaps the two most efficient ways to find the *last* index:

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

Both take only O(1) extra space and the *two* in-place reversals of the first solution are much faster than creating a reverse copy. Let’s compare it with the other solutions posted previously:

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

Benchmark results, my solutions are the red and green ones:

This is for searching a number in a list of a million numbers. The x-axis is for the location of the searched element: 0% means it’s at the start of the list, 100% means it’s at the end of the list. All solutions are fastest at location 100%, with the two `reversed`

solutions taking pretty much no time for that, the double-reverse solution taking a little time, and the reverse-copy taking a lot of time.

A closer look at the right end:

At location 100%, the reverse-copy solution and the double-reverse solution spend all their time on the reversals (`index()`

is instant), so we see that the two in-place reversals are about seven times as fast as creating the reverse copy.

The above was with `lst = list(range(1_000_000, 2_000_001))`

, which pretty much creates the int objects sequentially in memory, which is extremely cache-friendly. Let’s do it again after shuffling the list with `random.shuffle(lst)`

(probably less realistic, but interesting):

All got a lot slower, as expected. The reverse-copy solution suffers the most, at 100% it now takes about 32 times (!) as long as the double-reverse solution. And the `enumerate`

-solution is now second-fastest only after location 98%.

Overall I like the `operator.indexOf`

solution best, as it’s the fastest one for the last half or quarter of all locations, which are perhaps the more interesting locations if you’re actually doing `rindex`

for something. And it’s only a bit slower than the double-reverse solution in earlier locations.

All benchmarks done with CPython 3.9.0 64-bit on Windows 10 Pro 1903 64-bit.

As a small helper function:

```
def rindex(mylist, myvalue):
return len(mylist) - mylist[::-1].index(myvalue) - 1
```

Python lists have the `index()`

method, which you can use to find the position of the *first* occurrence of an item in a list. Note that `list.index()`

raises `ValueError`

when the item is not present in the list, so you may need to wrap it in `try`

/`except`

:

```
try:
idx = lst.index(value)
except ValueError:
idx = None
```

To find the position of the *last* occurrence of an item in a list efficiently (i.e. without creating a reversed intermediate list) you can use this function:

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

Using `max`

+ `enumerate`

to get last element occurrence

```
rindex = max(i for i, v in enumerate(your_list) if v == your_value)
```

This method can be more optimized than above

```
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]])
```

index of the first occurrence of x in s (at or after index i and before index j)