Vyhľadanie indexu položky vzhľadom na zoznam, ktorý ju obsahuje, v jazyku Python

Ako v jazyku Python získam index (1) pre zoznam ["foo", "bar", "baz"] a položku v zozname "bar"?

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

Odkaz: Data Structures > More on Lists

Nasledujú upozornenia

Všimnite si, že aj keď je to možno najčistejší spôsob, ako odpovedať na otázku ako je položená, index je dosť slabá súčasť API list a nepamätám si, kedy som ju naposledy v hneve použil. V komentároch ma upozornili, že keďže sa na túto odpoveď veľa odkazuje, mala by byť úplnejšia. Nasledujú niektoré upozornenia týkajúce sa list.index. Asi by stálo za to sa na začiatku pozrieť na docstring k nemu:

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

Lineárna časová zložitosť pri dĺžke zoznamu

Volanie index kontroluje každý prvok zoznamu v poradí, kým nenájde zhodu. Ak je váš zoznam dlhý a vy neviete, kde približne sa v zozname vyskytuje, toto hľadanie sa môže stať úzkym miestom. V takom prípade by ste mali zvážiť inú dátovú štruktúru. Všimnite si, že ak približne viete, kde sa má nájsť zhoda, môžete dať indexu nápovedu. Napríklad v tomto úryvku je l.index(999_999, 999_990, 1_000_000) zhruba o päť rádov rýchlejší ako priamy l.index(999_999), pretože prvý musí prehľadávať len 10 záznamov, zatiaľ čo druhý prehľadáva milión:

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

Vráti iba index prvej zhody so svojím argumentom

Volanie príkazu index prehľadáva zoznam v poradí, kým nenájde zhodu, a tam sa zastaví. Ak očakávate, že budete potrebovať indexy viacerých zhôd, mali by ste použiť chápanie zoznamu alebo generátorový výraz.

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

Na väčšine miest, kde by som kedysi použil index, teraz používam porozumenie zoznamu alebo generátorový výraz, pretože sú všeobecnejšie. Ak teda zvažujete, že siahnete po indexe, pozrite sa na tieto vynikajúce funkcie jazyka Python.

Throws if element not present in list

Volanie príkazu index má za následok chybu ValueError, ak prvok'nie je prítomný.

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

Ak sa položka nemusí nachádzať v zozname, mali by ste buď

  1. Najprv ju skontrolovať pomocou položka v mojom zozname (čistý, čitateľný prístup), alebo
  2. Zabaliť volanie index do bloku try/except, ktorý zachytí chybu ValueError (pravdepodobne rýchlejšie, aspoň ak je hľadaný zoznam dlhý a položka je zvyčajne prítomná).
Komentáre (2)

Pri učení sa jazyka Python je veľmi užitočné používať interaktívnu nápovedu:

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

class list(object)
 ...

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

ktorá vás často dovedie k hľadanej metóde.

Komentáre (1)

index() vráti prvý index hodnoty!

| index(...) | L.index(value, [start, [stop]]) -> celé číslo -- vráti prvý index hodnoty

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"])
Komentáre (3)