Domanda Trovare l'indice di un oggetto dato un elenco che lo contiene in Python


Per una lista ["foo", "bar", "baz"] e un elemento nell'elenco "bar", come ottengo il suo indice (1) in Python?


2235
2017-10-07 01:39


origine


risposte:


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

Riferimento: Strutture dati> Altro su elenchi

I caveat seguono

Si noti che mentre questo è forse il modo più pulito per rispondere alla domanda come richiesto, index è un componente piuttosto debole del list API, e non riesco a ricordare l'ultima volta che l'ho usato per la rabbia. Mi è stato fatto notare nei commenti che, poiché questa risposta è pesantemente referenziata, dovrebbe essere resa più completa. Alcuni avvertimenti circa list.index Seguire. Vale probabilmente la pena dare inizialmente un'occhiata alla docstring per questo:

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

Complessità di tempo lineare nella lunghezza dell'elenco

Un index call controlla ogni elemento della lista in ordine, fino a quando non trova una corrispondenza. Se la tua lista è lunga, e non sai approssimativamente dove si trova nella lista, questa ricerca potrebbe diventare un collo di bottiglia. In tal caso, dovresti prendere in considerazione una diversa struttura dei dati. Nota che se sai approssimativamente dove trovare la partita, puoi dare index un suggerimento. Ad esempio, in questo frammento, l.index(999_999, 999_990, 1_000_000) è all'incirca cinque ordini di grandezza più veloce del normale l.index(999_999), perché il primo deve cercare solo 10 voci, mentre il secondo cerca un milione:

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

Restituisce solo l'indice del prima partita alla sua argomentazione

Una chiamata a index cerca nell'elenco fino a quando non trova una corrispondenza, e si ferma lì. Se ti aspetti di aver bisogno di indici di più corrispondenze, dovresti usare una comprensione di lista o un'espressione di generatore.

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

La maggior parte dei posti in cui una volta avrei usato index, Ora uso una comprensione di lista o un'espressione generatore perché sono più generalizzabili. Quindi se stai pensando di raggiungere index, dai un'occhiata a queste eccellenti funzionalità di Python.

Genera se elemento non presente nella lista

Una chiamata a index risultati in a ValueError se l'oggetto non è presente.

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

Se l'articolo potrebbe non essere presente nella lista, dovresti

  1. Controlla prima con item in my_list (approccio pulito, leggibile), o
  2. Avvolgi il index chiama a try/except blocco che cattura ValueError (probabilmente più veloce, almeno quando l'elenco da cercare è lungo e l'elemento è solitamente presente.)

3296
2017-10-07 01:40



Una cosa che è molto utile nell'apprendimento di Python è l'uso della funzione di guida interattiva:

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

class list(object)
 ...

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

che ti condurrà spesso al metodo che stai cercando.


785
2017-10-07 13:19



La maggior parte delle risposte spiega come trovare un singolo indice, ma i loro metodi non restituiscono più indici se l'elemento è presente nell'elenco più volte. Uso enumerate():

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

Il index() la funzione restituisce solo la prima occorrenza, mentre enumerate() restituisce tutte le occorrenze.

Come una lista di comprensione:

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

Ecco anche un'altra piccola soluzione con itertools.count() (che è praticamente lo stesso approccio enumerato):

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

Questo è più efficiente per gli elenchi più grandi rispetto all'utilizzo 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



Per ottenere tutti gli indici:

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

123
2018-06-25 15:07



index()restituisce il primo indice di valore!

| indice(...)
   | L.index (value, [start, [stop]]) -> intero - restituisce il primo indice di valore

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



Un problema si presenterà se l'elemento non è nella lista. Questa funzione gestisce il problema:

# 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



Devi impostare una condizione per verificare se l'elemento che stai cercando è nell'elenco

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

39
2018-05-26 04:26



Tutte le funzioni proposte qui riproducono il comportamento inerente del linguaggio ma oscurano ciò che sta accadendo.

[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

Perché scrivere una funzione con gestione delle eccezioni se la lingua fornisce i metodi per fare ciò che si desidera da sé?


34
2018-05-16 16:45



Se vuoi tutti gli indici, allora puoi usare 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),)

È una soluzione chiara e leggibile.


27
2017-11-17 19:05