Python-Listen verfügen über die index()Methode, mit der Sie die Position des ersten Auftretens eines Elements in einer Liste ermitteln können. Beachten Sie, dass dies list.index()ausgelöst wird, ValueErrorwenn das Element nicht in der Liste vorhanden ist. Daher müssen Sie es möglicherweise in try/ einschließen except:
Mit der folgenden Funktion können Sie die Position des letzten Auftretens eines Elements in einer Liste effizient ermitteln (dh ohne eine umgekehrte Zwischenliste zu erstellen):
defrindex(lst, value):for i, v in enumerate(reversed(lst)):
if v == value:
return len(lst) - i - 1# return the index in the original listreturnNone
print(rindex([1, 2, 3], 3)) # 2
print(rindex([3, 2, 1, 3], 3)) # 3
print(rindex([3, 2, 1, 3], 4)) # None
Beide benötigen nur O (1) zusätzlichen Platz und die beiden direkten Umkehrungen der ersten Lösung sind viel schneller als das Erstellen einer Umkehrkopie. Vergleichen wir es mit den anderen zuvor veröffentlichten Lösungen:
defrindex(lst, value):return len(lst) - lst[::-1].index(value) - 1defrindex(lst, value):return len(lst) - next(i for i, val in enumerate(reversed(lst)) if val == value) - 1
Benchmark-Ergebnisse, meine Lösungen sind die roten und grünen:
Dies dient zum Suchen einer Nummer in einer Liste mit einer Million Nummern. Die x-Achse steht für die Position des gesuchten Elements: 0% bedeutet, dass es am Anfang der Liste steht, 100% bedeutet, dass es am Ende der Liste steht. Alle Lösungen sind am Standort zu 100% am schnellstenreversed Lösungen so gut wie keine Zeit dafür benötigen, die Double-Reverse-Lösung etwas Zeit in Anspruch nimmt und die Reverse-Kopie viel Zeit in Anspruch nimmt.
Ein genauerer Blick auf das rechte Ende:
Am Standort 100% verbringen die Reverse-Copy-Lösung und die Double-Reverse-Lösung ihre ganze Zeit mit den Umkehrungen (index() erfolgt sofort). Wir sehen also, dass die beiden vorhandenen Umkehrungen etwa siebenmal so schnell sind wie das Erstellen der Umkehrkopie.
Das obige war mit lst = list(range(1_000_000, 2_000_001)), das die int-Objekte so ziemlich sequentiell im Speicher erstellt, was extrem cache-freundlich ist. Machen wir es noch einmal, nachdem wir die Liste mit gemischt haben random.shuffle(lst)(wahrscheinlich weniger realistisch, aber interessant):
Wie erwartet wurde alles viel langsamer. Die Reverse-Copy-Lösung leidet am meisten. Mit 100% dauert sie jetzt etwa 32-mal (!) So lange wie die Double-Reverse-Lösung. Und die enumerate-Lösung ist jetzt erst nach Standort 98% die zweitschnellste.
Insgesamt gefällt mir die operator.indexOfLösung am besten, da sie die schnellste für die letzte Hälfte oder das letzte Viertel aller Standorte ist. Dies sind möglicherweise die interessanteren Standorte, wenn Sie dies tatsächlich tunrindex etwas . Und es ist nur ein bisschen langsamer als die Double-Reverse-Lösung an früheren Standorten.
Alle Benchmarks mit CPython 3.9.0 64-Bit unter Windows 10 Pro 1903 64-Bit.
defrindex(iterable, value):try:
return len(iterable) - next(i for i, val in enumerate(reversed(iterable)) if val == value) - 1except StopIteration:
raise ValueError
Antworten:
Sequenzen haben eine Methode,
index(value)
die den Index des ersten Auftretens zurückgibt - in Ihrem Fall wäre diesverts.index(value)
.Sie können es ausführen
verts[::-1]
, um den letzten Index herauszufinden. Hier wäre daslen(verts) - 1 - verts[::-1].index(value)
quelle
Wenn Sie nach dem Index des letzten Auftretens von
myvalue
in suchenmylist
:len(mylist) - mylist[::-1].index(myvalue) - 1
quelle
ValueError
wennmyvalue
nicht vorhanden inmylist
.Als kleine Hilfsfunktion:
def rindex(mylist, myvalue): return len(mylist) - mylist[::-1].index(myvalue) - 1
quelle
Python-Listen verfügen über die
index()
Methode, mit der Sie die Position des ersten Auftretens eines Elements in einer Liste ermitteln können. Beachten Sie, dass dieslist.index()
ausgelöst wird,ValueError
wenn das Element nicht in der Liste vorhanden ist. Daher müssen Sie es möglicherweise intry
/ einschließenexcept
:try: idx = lst.index(value) except ValueError: idx = None
Mit der folgenden Funktion können Sie die Position des letzten Auftretens eines Elements in einer Liste effizient ermitteln (dh ohne eine umgekehrte Zwischenliste zu erstellen):
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
quelle
Vielleicht die zwei effizientesten Wege, um den letzten Index zu finden :
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
Beide benötigen nur O (1) zusätzlichen Platz und die beiden direkten Umkehrungen der ersten Lösung sind viel schneller als das Erstellen einer Umkehrkopie. Vergleichen wir es mit den anderen zuvor veröffentlichten Lösungen:
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-Ergebnisse, meine Lösungen sind die roten und grünen:
Dies dient zum Suchen einer Nummer in einer Liste mit einer Million Nummern. Die x-Achse steht für die Position des gesuchten Elements: 0% bedeutet, dass es am Anfang der Liste steht, 100% bedeutet, dass es am Ende der Liste steht. Alle Lösungen sind am Standort zu 100% am schnellsten
reversed
Lösungen so gut wie keine Zeit dafür benötigen, die Double-Reverse-Lösung etwas Zeit in Anspruch nimmt und die Reverse-Kopie viel Zeit in Anspruch nimmt.Ein genauerer Blick auf das rechte Ende:
Am Standort 100% verbringen die Reverse-Copy-Lösung und die Double-Reverse-Lösung ihre ganze Zeit mit den Umkehrungen (
index()
erfolgt sofort). Wir sehen also, dass die beiden vorhandenen Umkehrungen etwa siebenmal so schnell sind wie das Erstellen der Umkehrkopie.Das obige war mit
lst = list(range(1_000_000, 2_000_001))
, das die int-Objekte so ziemlich sequentiell im Speicher erstellt, was extrem cache-freundlich ist. Machen wir es noch einmal, nachdem wir die Liste mit gemischt habenrandom.shuffle(lst)
(wahrscheinlich weniger realistisch, aber interessant):Wie erwartet wurde alles viel langsamer. Die Reverse-Copy-Lösung leidet am meisten. Mit 100% dauert sie jetzt etwa 32-mal (!) So lange wie die Double-Reverse-Lösung. Und die
enumerate
-Lösung ist jetzt erst nach Standort 98% die zweitschnellste.Insgesamt gefällt mir die
operator.indexOf
Lösung am besten, da sie die schnellste für die letzte Hälfte oder das letzte Viertel aller Standorte ist. Dies sind möglicherweise die interessanteren Standorte, wenn Sie dies tatsächlich tunrindex
etwas . Und es ist nur ein bisschen langsamer als die Double-Reverse-Lösung an früheren Standorten.Alle Benchmarks mit CPython 3.9.0 64-Bit unter Windows 10 Pro 1903 64-Bit.
quelle
Diese Methode kann optimiert werden als oben
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
quelle
Index des ersten Auftretens von x in s (am oder nach dem Index i und vor dem Index j)
quelle