If you are actually using just single letters like shown in your example, then str.rindex would work handily. This raises a ValueError if there is no such item, the same error class as list.index would raise. 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:
>>> 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 long, it may be more efficient to use a reverse iteration and avoid the copy:
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')
Answer from wim on Stack OverflowIf you are actually using just single letters like shown in your example, then str.rindex would work handily. This raises a ValueError if there is no such item, the same error class as list.index would raise. 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:
>>> 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 long, it may be more efficient to use a reverse iteration and avoid the copy:
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
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. No nexts, lambdas, reverseds or itertools required.
Finding last index of some value in a list in Python
finding the last occurrence of an item in a list python - Stack Overflow
python - How to find the last occurrence of item in nested list? - Stack Overflow
python - Find last occurence of item in a list excluding the last element - Stack Overflow
Let's say v is a list or a tuple.
To find the last occurrence of value in v we would need to compute len(v) - 1 - v[::-1].index(value)
Why is this? Why must we subtract the last term from len(v) - 1? Why does simply writing v[::-1].index(value) give the wrong result?
In fact, what does v[::-1] actually do? Doesn't it reverse the list/tuple? If it does reverse it, then v[::-1].index(value) should give the last occurrence of value in v, but for some reason it does not work like that.
To do it efficiently, enumerate the list in reverse order and return the index of the first matching item (or None by default), e.g.:
def PositionLast(x, s):
for i, v in enumerate(reversed(s)):
if v == x:
return len(s) - i - 1 # return the index in the original list
return None
Avoid reversing the list using slice notation (e.g. s[::-1]) as that would create a new reversed list in memory, which is not necessary for the task.
Your logic is incorrect, because you return the count if i==x and you have an extra loop at the trailing of your function.
Instead you loop over the reverse forms of enumerate of your list and return the index of first occurrence :
def PositionLast (x,s):
return next(i for i,j in list(enumerate(s))[::-1] if j == x)
Demo:
print PositionLast (2, [2,5,2,3,5,3])
2
print PositionLast (3, [2,5,2,3,5,3])
5
print PositionLast (5, [2,5,2,3,5,3])
4
If you want all the last indices of each item in ll present in mm, then:
ll = [500,500,500,501,500,502,500]
mm = [499,501,502]
d = {v:k for k,v in enumerate(ll) if v in mm}
# {501: 3, 502: 5}
It's probably worth creating a set from mm first to make it an O(1) lookup, instead of O(N), but for three items, it's really not worth it.
Following @Apero's concerns about retaining missing indices as None and also using a hash lookup to make it an O(1) lookup...
# Build a key->None dict for all `mm`
d = dict.fromkeys(mm)
# Update `None` values with last index using a gen-exp instead of dict-comp
d.update((v,k) for k,v in enumerate(ll) if v in d)
# {499: None, 501: 3, 502: 5}
results = {}
reversed = ll[::-1]
for item in mm:
try:
index = ((len(ll) - 1) - reversed.index(item))
except ValueError:
index = None
finally:
results[item] = index
print results
Output:
{499: None, 501: 3, 502: 5}
Start from end and go backwards:
def get_far_end(symbol,lot):
for i in range(len(lot)-1,-1,-1):
for j in range(len(lot[i])-1,-1,-1):
if lot[i][j] == symbol:
return i ,j
return None
The problem of your algorithm is that you are returning as fas as you find the first occurrence of the element.
So What you should do is, when you find j==symbol save the both index and keep ruuning your matrix
after all loops, you will have the last occurance of your symbol..
Or, a second aproach is, starts from the end, and run the inverse matrix, in this case, you can return the first occurence of j==symbol
How about:
start = len(listData) - listData[::-1].index(datum)
(ie. the last index is the first index from the reversed list)
Here you go:
>>> listData = ['H66', 'B35', 'L21', 'B35', 'H66', 'J02', 'J04', 'L21', 'J20']
>>> def return_last(x):
... return len(listData)-listData[::-1].index(x)-1
...
>>> return_last("L21")
7
>>> return_last("H66")
4