Frage Ermitteln des Index eines Elements in einer Liste, die ihn in Python enthält


Für eine Liste ["foo", "bar", "baz"] und ein Element in der Liste "bar", wie bekomme ich seinen Index (1) in Python?


2238
2017-10-07 01:39


Ursprung


Antworten:


>>> ["foo", "bar", "baz"].index("bar")
1

Referenz: Datenstrukturen> Mehr zu Listen

Vorbehalte folgen

Beachten Sie, dass dies vielleicht der sauberste Weg ist, die Frage zu beantworten wie gefragt, index ist eine eher schwache Komponente der list API, und ich kann mich nicht an das letzte Mal erinnern, als ich es im Zorn benutzt habe. In den Kommentaren wurde darauf hingewiesen, dass diese Antwort, da sie sehr referenziert ist, vollständiger sein sollte. Einige Vorbehalte gegen list.index Folgen. Es lohnt sich, zunächst einmal den Docstring dazu zu betrachten:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

Lineare Zeit-Komplexität in Listenlänge

Ein index call überprüft jedes Element der Liste in der richtigen Reihenfolge, bis es eine Übereinstimmung findet. Wenn Ihre Liste lang ist und Sie nicht genau wissen, wo in der Liste sie auftritt, könnte diese Suche zu einem Engpass werden. In diesem Fall sollten Sie eine andere Datenstruktur berücksichtigen. Beachten Sie, dass Sie, wenn Sie ungefähr wissen, wo Sie das Spiel finden, geben können index ein Hinweis. Zum Beispiel, in diesem Ausschnitt, l.index(999_999, 999_990, 1_000_000) ist ungefähr fünf Größenordnungen schneller als gerade l.index(999_999), da der erstere nur 10 Einträge durchsuchen muss, während der zweite eine Million sucht:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

Gibt nur den Index der erstes Spiel zu seinem Argument

Ein Anruf an index Durchsucht die Liste in der Reihenfolge, bis sie eine Übereinstimmung findet, und hält dort an. Wenn Sie Indizes für mehr Übereinstimmungen benötigen, sollten Sie ein Listenverständnis oder einen Generatorausdruck verwenden.

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2

Die meisten Orte wo ich einmal benutzt hätte index, Verwende ich jetzt ein Listenverständnis oder einen Generatorausdruck, weil sie allgemeiner verallgemeinerbar sind. Also, wenn Sie darüber nachdenken, nach etwas zu greifen indexSehen Sie sich diese exzellenten Python-Funktionen an.

Wird ausgelöst, wenn das Element nicht in der Liste vorhanden ist

Ein Anruf an index ergibt a ValueError wenn das Element nicht vorhanden ist.

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

Wenn das Element möglicherweise nicht in der Liste vorhanden ist, sollten Sie entweder

  1. Überprüfen Sie zuerst mit item in my_list (sauberer, lesbarer Ansatz), oder
  2. Wickeln Sie die index Anruf in einem try/except blockieren, der fängt ValueError (wahrscheinlich schneller, zumindest wenn die zu suchende Liste lang ist und das Objekt normalerweise vorhanden ist.)

3299
2017-10-07 01:40



Eine Sache, die beim Erlernen von Python wirklich hilfreich ist, ist die Verwendung der interaktiven Hilfefunktion:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

was dich oft zu der Methode führt, nach der du suchst.


785
2017-10-07 13:19



Die Mehrheit der Antworten erklärt, wie man findet ein einzelner Index, aber ihre Methoden geben nicht mehrere Indizes zurück, wenn sich das Element mehrfach in der Liste befindet. Benutzen enumerate():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

Das index() Funktion gibt nur das erste Vorkommen zurück, während enumerate() gibt alle Vorkommen zurück.

Als Listenverständnis:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

Hier ist auch eine andere kleine Lösung mit itertools.count() (das ist ziemlich die gleiche Vorgehensweise wie aufzuzählen):

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

Dies ist effizienter für größere Listen als die Verwendung enumerate():

$ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop

446
2018-06-19 22:31



Um alle Indizes zu erhalten:

 indexes = [i for i,x in enumerate(xs) if x == 'foo']

123
2018-06-25 15:07



index()gibt das zurück zuerst Wertindex!

| Index(...)
   | L.index (value, [start, [stop]]) -> integer - gibt den ersten Index des Wertes zurück

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])

105
2017-08-30 09:40



Ein Problem wird auftreten, wenn das Element nicht in der Liste ist. Diese Funktion behandelt das Problem:

# if element is found it returns index of element else returns None

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None

67
2018-04-16 10:19



a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']

57
2017-08-21 12:01



Sie müssen eine Bedingung festlegen, um zu prüfen, ob das Element, das Sie suchen, in der Liste enthalten ist

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None

39
2018-05-26 04:26



Alle hier vorgeschlagenen Funktionen reproduzieren inhärentes Sprachverhalten, verdecken jedoch, was vor sich geht.

[i for i in range(len(mylist)) if mylist[i]==myterm]  # get the indices

[each for each in mylist if each==myterm]             # get the items

mylist.index(myterm) if myterm in mylist else None    # get the first index and fail quietly

Warum sollte man eine Funktion mit Ausnahmebehandlung schreiben, wenn die Sprache die Methoden zur Verfügung stellt, um das zu tun, was Sie wollen?


34
2018-05-16 16:45



Wenn Sie alle Indizes möchten, dann können Sie verwenden NumPy:

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 ist klar, lesbare Lösung.


27
2017-11-17 19:05