De index van een item vinden in een lijst die het bevat in Python

Voor een lijst ["foo", "bar", "baz"] en een item in de lijst "bar", hoe krijg ik de index (1) ervan in Python?

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

Referentie: Data Structures > Meer over Lijsten

Caveats follow

Merk op dat terwijl dit misschien de schoonste manier is om de vraag te beantwoorden zoals gevraagd, index is een vrij zwak onderdeel van de lijst API, en ik kan me niet herinneren de laatste keer dat ik het in woede heb gebruikt. Het's gewezen op mij in de commentaren dat, omdat dit antwoord is zwaar verwezen, het moet meer volledig worden gemaakt. Enkele voorbehouden over list.index volgen. Het is waarschijnlijk de moeite waard om eerst de docstring ervoor te bekijken:

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

Lineaire tijd-complexiteit in lijst lengte

Een index aanroep controleert elk element van de lijst in volgorde, totdat het een overeenkomst vindt. Als je lijst lang is, en je weet niet ongeveer waar in de lijst het voorkomt, dan kan dit zoeken een bottleneck worden. In dat geval moet u een andere gegevensstructuur overwegen. Merk op dat als je ongeveer weet waar je de overeenkomst moet vinden, je index een hint kunt geven. In dit voorbeeld is l.index(999_999, 999_990, 1_000_000) ruwweg vijf orden van grootte sneller dan l.index(999_999), omdat de eerste maar 10 regels hoeft te doorzoeken, terwijl de tweede een miljoen regels doorzoekt:

>>> 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

Geeft alleen de index van de eerste overeenkomst met zijn argument

Een oproep aan index doorzoekt de lijst in volgorde totdat het een overeenkomst vindt, en stopt daar. Als je verwacht indexen van meer overeenkomsten nodig te hebben, moet je een list comprehension gebruiken, of een generator expressie.

>>> [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

Op de meeste plaatsen waar ik ooit index zou hebben gebruikt, gebruik ik nu een list comprehension of generator expressie omdat die meer generaliseerbaar zijn. Dus als je overweegt om naar index te grijpen, kijk dan eens naar deze uitstekende python functies.

Geeft een fout als het element niet in de lijst voorkomt

Een oproep aan index resulteert in een ValueError als het item'niet aanwezig is.

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

Als het item mogelijk niet in de lijst aanwezig is, moet u ofwel

  1. Controleer het eerst met item in my_list (schone, leesbare aanpak), of
    1. Wikkel de index aanroep in een try/except blok dat ValueError afvangt (waarschijnlijk sneller, tenminste als de te doorzoeken lijst lang is, en het item meestal wel aanwezig is).
Commentaren (2)

Een ding dat echt nuttig is bij het leren van Python is het gebruik van de interactieve helpfunctie:

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

class list(object)
 ...

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

die je vaak zal leiden naar de methode die je zoekt.

Commentaren (1)

index() geeft de eerste index van waarde terug!

| index(...) | L.index(waarde, [start, [stop]]) -> integer -- eerste index van waarde teruggeven

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"])
Commentaren (3)