If you don't have any other indexes or sorted information for your objects, then you will have to iterate until such an object is found:
next(obj for obj in objs if obj.val == 5)
This is however faster than a complete list comprehension. Compare these two:
[i for i in xrange(100000) if i == 1000][0]
next(i for i in xrange(100000) if i == 1000)
The first one needs 5.75ms, the second one 58.3µs (100 times faster because the loop 100 times shorter).
Answer from eumiro on Stack OverflowIf you don't have any other indexes or sorted information for your objects, then you will have to iterate until such an object is found:
next(obj for obj in objs if obj.val == 5)
This is however faster than a complete list comprehension. Compare these two:
[i for i in xrange(100000) if i == 1000][0]
next(i for i in xrange(100000) if i == 1000)
The first one needs 5.75ms, the second one 58.3µs (100 times faster because the loop 100 times shorter).
This will return the object if found, else it will return "not found"
a = [100, 200, 300, 400, 500]
def search(b):
try:
k = a.index(b)
return a[k]
except ValueError:
return 'not found'
print(search(500))
First occurrence of a number in python list - Stack Overflow
How can I find a first occurrence of a string from a list in another string in python - Stack Overflow
Finding first and last index of some value in a list in Python - Stack Overflow
python - Finding the index of the first occurrence of any item in a list - Stack Overflow
Videos
Use index to find the first occurrence of an item in a list
>>> l = [0,0,0,0,0,1,1,1,1,1,1,1]
>>> l.index(0)
0
>>> l.index(1)
5
A solution that works for more than just 0 and 1 can be based to a set containing the elements we encountered so far:
l = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
s = set()
for x in l:
if x not in s:
print("first occurrence of %s" % x)
s.add(x)
print(x)
Result:
first occurrence of 0
0
0
0
0
0
first occurrence of 1
1
1
1
1
1
1
1
This seems work well and tells you what word it found (although that could be left out):
words = 'a big red dog car woman mountain are the ditch'.split()
sentence = 'her smooth lips reminded me of the front of a big red car lying in the ditch'
from sys import maxint
def find(word, sentence):
try:
return sentence.index(word), word
except ValueError:
return maxint, None
print min(find(word, sentence) for word in words)
A one liner with list comprehension would be
return min([index for index in [bigString.find(word, startIndex) for word in wordList] if index != -1])
But I would argue if you split it into two lines its more readable
indexes = [bigString.find(word, startIndex) for word in wordList]
return min([index for index in indexes if index != -1])
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)
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
import operator
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.
Turn the list to a set then use .index:
output = [my_list.index(elem) for elem in set(my_list)]
Since set is unordered you may want to sort the output:
output = sorted(my_list.index(elem) for elem in set(my_list))
Full example:
>>> my_list = ['hi', 'babe', 'hi', 'babe', 'key', 'key']
>>> output = sorted(my_list.index(elem) for elem in set(my_list))
>>> output
[0, 1, 4]
You can use a set to keep track of already-seen elements and use a loop or list comprehension to get whether each element is the first of its kind. Then, use enumerate to get the indices.
>>> seen = set()
>>> [int(not(s in seen or seen.add(s))) for s in my_list]
[1, 1, 0, 0, 1, 0]
>>> [i for i, e in enumerate(_) if e]
[0, 1, 4]