4394 Stimmen

Wie finde ich den Index für ein bestimmtes Element in einer Liste?

Gegeben eine Liste ["foo", "bar", "baz"] und ein Element in der Liste "bar", wie erhalte ich seinen Index 1?

16 Stimmen

Übersetzung: Kehren Sie zurück: [1] Der niedrigste Index im Falle mehrerer Instanzen von "bar", [2] Alle Indizes von "bar"?

7 Stimmen

A) Ist es garantiert, dass der Eintrag in der Liste ist, oder wie sollten wir den Fehlerfall behandeln? (None zurückgeben/ ValueError werfen) b) Sind Listeneinträge garantiert einzigartig, und sollten wir den ersten Index eines Treffers zurückgeben oder alle Indizes?

1 Stimmen

Betrachten Sie die Antworten mit numpy-Integration, numpy-Arrays sind weitaus effizienter als Python-Listen. Wenn die Liste kurz ist, ist es kein Problem, eine Kopie davon aus einer Python-Liste zu machen. Wenn nicht, sollten Sie vielleicht erwägen, die Elemente gleich von Anfang an in einem numpy-Array zu speichern.

8voto

Caveman Punkte 1734

Für einen Vergleichbaren

# Wirft ValueError, wenn nichts gefunden wird
some_list = ['foo', 'bar', 'baz'].index('baz')
# some_list == 2

Benutzerdefinierter Prädikat

some_list = [item1, item2, item3]

# Wirft StopIteration, wenn nichts gefunden wird
# *außer* Sie einen zweiten Parameter für `next` bereitstellen
index_of_value_you_like = next(
    i for i, item in enumerate(some_list)
    if item.matches_your_criteria())

Index aller Elemente nach Prädikat finden

index_of_staff_members = [
    i for i, user in enumerate(users)
    if user.is_staff()]

0 Stimmen

idx = next((i for i, v im enumerate(ls) if v == chk), -1) um ein ähnliches Verhalten wie str.index(chk) zu erhalten.

0 Stimmen

@tejasvi88 Hat beschlossen, etwas zusätzliche Arbeit in die Antwort zu stecken

7voto

Coder123 Punkte 79
name = "bar"
liste = [["foo", 1], ["bar", 2], ["baz", 3]]
neue_liste = []
for element in liste:
    neue_liste.append(element[0])
print(neue_liste)
try:
    position = neue_liste.index(name)
except:
    position = -1
print(position)

Dies berücksichtigt auch, wenn der String nicht in der Liste enthalten ist, in diesem Fall ist position = -1

6voto

jihed gasmi Punkte 251

Da Python-Listen nullbasiert sind, können wir die integrierte zip-Funktion wie folgt verwenden:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

wo "haystack" die betreffende Liste ist und "needle" das gesuchte Element ist.

(Hinweis: Hier iterieren wir über i, um die Indizes zu erhalten, aber wenn wir uns eher auf die Elemente konzentrieren möchten, können wir zu j wechseln.)

5 Stimmen

[i for i,j in enumerate(haystack) if j==‘needle’] ist kompakter und lesbarer, denke ich.

5voto

Vlad Bezden Punkte 71128

Wenn Sie einmal einen Index finden möchten, ist die Verwendung der "index"-Methode in Ordnung. Wenn Sie jedoch mehrmals nach Ihren Daten suchen möchten, empfehle ich die Verwendung des bisect-Moduls. Beachten Sie, dass bei der Verwendung des Bisect-Moduls die Daten sortiert sein müssen. Sortieren Sie also die Daten einmal und verwenden Sie dann Bisect. Die Verwendung des bisect-Moduls auf meinem eigenen Gerät ist etwa 20 Mal schneller als die Verwendung der Index-Methode.

Hier ist ein Beispielcode unter Verwendung der Syntax von Python 3.8 und höher:

import bisect
from timeit import timeit

def bisect_search(container, value):
    return (
      index 
      if (index := bisect.bisect_left(container, value)) < len(container) 
      and container[index] == value else -1
    )

data = list(range(1000))
# Wert, nach dem gesucht werden soll
value = 666

# Anzahl der Tests
ttt = 1000

t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)

print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")

Ergebnis:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

0 Stimmen

"Die Verwendung des Bisect-Moduls auf meinem Computer ist ungefähr 20-mal schneller als die Verwendung der Index-Methode." ist eine etwas ungenaue Art, die Beziehung zwischen den beiden Algorithmen zu beschreiben. Es handelt sich nicht um eine lineare Beziehung, sodass bei kleinen Listen von beispielsweise 10 Elementen beide Algorithmen ungefähr gleich gut funktionieren sollten. Bei etwas größeren Listen können Sie jedoch einen Unterschied feststellen. Bei massiven Listen kann die binäre Suche tausendmal schneller sein.

5voto

FatihAkici Punkte 4131

Wenn Leistung wichtig ist:

In zahlreichen Antworten wird erwähnt, dass die eingebaute Methode list.index(item) ein O(n) Algorithmus ist. Es ist in Ordnung, wenn Sie dies einmal ausführen müssen. Wenn Sie jedoch mehrmals auf die Indizes von Elementen zugreifen müssen, macht es mehr Sinn, zuerst ein Wörterbuch (O(n)) von Item-Index-Paaren zu erstellen und dann den Index bei O(1) jedes Mal abzurufen, wenn Sie ihn benötigen.

Wenn Sie sicher sind, dass die Elemente in Ihrer Liste nie doppelt vorkommen, können Sie ganz einfach:

myList = ["foo", "bar", "baz"]

# Das Wörterbuch erstellen
myDict = dict((e,i) for i,e in enumerate(myList))

# Suche
myDict["bar"] # Gibt 1 zurück
# myDict.get("blah"), wenn Sie nicht möchten, dass ein Fehler auftritt, wenn das Element nicht gefunden wird.

Wenn Sie doppelte Elemente haben und alle ihre Indizes zurückgeben müssen:

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Das Wörterbuch erstellen
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Suche
myDict["foo"] # Gibt [0, 4] zurück

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X