Gegeben eine Liste ["foo", "bar", "baz"]
und ein Element in der Liste "bar"
, wie erhalte ich seinen Index 1
?
Diese Antwort sollte besser hier gepostet werden: stackoverflow.com/questions/6294179/…
Gegeben eine Liste ["foo", "bar", "baz"]
und ein Element in der Liste "bar"
, wie erhalte ich seinen Index 1
?
Ein Problem wird auftreten, wenn das Element nicht in der Liste ist. Diese Funktion behandelt das Problem:
# gibt den Index des Elements zurück, wenn das Element gefunden wird, ansonsten None
def find_element_in_list(element, list_element):
try:
index_element = list_element.index(element)
return index_element
except ValueError:
return None
@stefanct Die Zeitkomplexität ist immer noch linear, aber es wird zweimal durch die Liste iteriert.
Wenn Sie alle Indizes möchten, können Sie NumPy verwenden:
import numpy as np
array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)
Es handelt sich um eine klare, lesbare Lösung.
Dies ist der beste, den ich gelesen habe. 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 erstellen. Wenn nicht, sollte der Entwickler vielleicht in Betracht ziehen, die Elemente von Anfang an in einem numpy-Array zu speichern.
Den Index eines Elements in Python finden, das sich in einer Liste befindet
Für eine Liste
["foo", "bar", "baz"]
und ein Element in der Liste"bar"
, wie können Sie auf saubere Weise den Index (1) in Python erhalten?
Natürlich gibt es die Indexmethode, die den Index des ersten Vorkommens zurückgibt:
>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1
Es gibt ein paar Probleme mit dieser Methode:
ValueError
Wenn der Wert fehlen könnte, müssen Sie den ValueError
abfangen.
Sie können dies mit einer wiederverwendbaren Definition wie dieser tun:
def index(a_list, value):
try:
return a_list.index(value)
except ValueError:
return None
Und verwenden Sie es wie folgt:
>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1
Und der Nachteil dabei ist, dass Sie wahrscheinlich überprüfen müssen, ob der zurückgegebene Wert ist
oder nicht ist
None:
ergebnis = index(a_list, value)
if ergebnis is not None:
mach_etwas(ergebnis)
Wenn es mehrere Vorkommen geben könnte, erhalten Sie mit list.index
keine vollständigen Informationen:
>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar') # nichts bei Index 3?
1
Sie könnten die Indizes in eine Listenumfassung aufzählen:
>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]
Wenn Sie keine Vorkommen haben, können Sie dies mit einem booleschen Check des Ergebnisses überprüfen oder einfach nichts tun, wenn Sie über die Ergebnisse iterieren:
indizes = [index for index, v in enumerate(l) if v == 'boink']
for index in indizes:
mach_etwas(index)
Wenn Sie pandas haben, können Sie diese Informationen einfach mit einem Series-Objekt abrufen:
>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0 foo
1 bar
2 baz
3 bar
dtype: object
Ein Vergleichstest liefert eine Reihe von Booleans:
>>> series == 'bar'
0 False
1 True
2 False
3 True
dtype: bool
Übergeben Sie diese Booleanserie an die Serie über die Indexnotation, und Sie erhalten nur die übereinstimmenden Elemente:
>>> series[series == 'bar']
1 bar
3 bar
dtype: object
Wenn Sie nur die Indizes möchten, gibt das Indexattribut eine Serie von Ganzzahlen zurück:
>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')
Und wenn Sie sie in einer Liste oder einem Tupel möchten, übergeben Sie sie einfach an den Konstruktor:
>>> list(series[series == 'bar'].index)
[1, 3]
Ja, Sie könnten auch eine Listenumfassung mit enumerate verwenden, aber das ist meiner Meinung nach nicht so elegant - Sie führen Tests auf Gleichheit in Python durch, anstatt den in C geschriebenen integrierten Code damit umzugehen zu lassen:
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
Das XY-Problem besteht darin, nach Ihrer versuchten Lösung zu fragen, anstatt nach Ihrem tatsächlichen Problem.
Warum denken Sie, dass Sie den Index eines Elements in einer Liste benötigen?
Wenn Sie den Wert bereits kennen, warum ist es dann wichtig, wo er sich in einer Liste befindet?
Wenn der Wert nicht vorhanden ist, ist das Abfangen des ValueError
ziemlich umständlich - und ich ziehe es vor, das zu vermeiden.
Normalerweise iteriere ich sowieso über die Liste, also behalte ich normalerweise einen Zeiger auf alle interessanten Informationen, um den Index mit enumerate zu erhalten.
Wenn Sie Daten bearbeiten, sollten Sie wahrscheinlich pandas verwenden - das bietet wesentlich elegantere Tools als die reinen Python-Workarounds, die ich gezeigt habe.
Ich erinnere mich nicht daran, list.index
verwendet zu haben. Ich habe jedoch die Python-Standardbibliothek durchsucht und einige ausgezeichnete Verwendungen davon gefunden.
Es gibt viele Verwendungen davon in idlelib
, für GUI und Textanalyse.
Das Modul keyword
verwendet es, um Kommentarmarker im Modul zu finden, um automatisch die Liste der Schlüsselwörter darin über Metaprogrammierung neu zu generieren.
In Lib/mailbox.py scheint es verwendet zu werden, um eine geordnete Zuordnung zu erhalten:
schlüssel_liste[schlüssel_liste.index(alt)] = neu
und
del schlüssel_liste[schlüssel_liste.index(schlüssel)]
In Lib/http/cookiejar.py wird anscheinend verwendet, um den nächsten Monat zu erhalten:
monat = MONATE_LOWER.index(monat.lower())+1
In Lib/tarfile.py ähnlich wie in distutils, um ein Segment bis zu einem Element zu erhalten:
mitglieder = mitglieder[:mitglieder.index(tarinfo)]
In Lib/pickletools.py:
numtopop = vorher.index(markobject)
Was diese Verwendungen gemeinsam zu haben scheinen, ist, dass sie auf Listen mit begrenzten Größen arbeiten (wichtig aufgrund der O(n)-Suchzeit für list.index
) und hauptsächlich in Analyse (und UI im Fall von Idle) verwendet werden.
Obwohl es Anwendungsfälle dafür gibt, sind sie ziemlich ungewöhnlich. Wenn Sie sich auf der Suche nach dieser Antwort wiederfinden, fragen Sie sich, ob das, was Sie tun, die direkteste Verwendung der vom Sprach bereitgestellten Tools für Ihren Anwendungsfall ist.
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.
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.
1 Stimmen
Ich stimme dafür, diese Frage zu schließen (aus Protest), weil es bereits 42 nicht gelöschte Antworten gibt (und 16 weitere gelöschte) für eine einfache, Einzeiler-Referenzfrage, bei der fast alle den gleichen Kernfunktion im verwenden (wie sie es sollten, weil es der einzige vernünftige und gesunde Ansatz für das Problem ist und alles darum herum nur Fehlerüberprüfung oder kreatives Neuinterpretieren der Spezifikation ist, was immer noch nur einen anderen vernünftigen, gesunden Ansatz zum erweiterten Problem hinterlässt).
0 Stimmen
Es gibt keine realistische Chance, dass in zukünftigen Versionen von Python ein besserer Ansatz möglich wird, da der vorhandene Ansatz bereits das Aufrufen einer einzigen integrierten Methode in der Liste ist - so einfach wie es nur geht.