Trovare l'indice di un elemento in un elenco


3184

Dato un elenco ["foo", "bar", "baz"]e un elemento nell'elenco "bar", come posso ottenere il suo indice ( 1) in Python?


6
Stai tornando: [1] L'indice più basso nel caso in cui vi siano più istanze di "bar", [2] Tutti gli indici di "bar"?
Ṃųỻịgǻňạcểơửṩ,

4
a) È garantito che l'elemento sia nell'elenco, oppure come dovremmo gestire il caso di errore? (return None / raise ValueError) b) Le voci dell'elenco sono garantite come univoche e dovremmo restituire il primo indice di una corrispondenza o tutti gli indici?
smci,

Visualizza le risposte con l'integrazione numpy, gli array numpy sono molto più efficienti degli elenchi Python. Se l'elenco è breve, non è un problema crearne una copia da un elenco Python, se non lo è, forse dovresti considerare di memorizzare gli elementi nell'array numpy in primo luogo.
Athanassios,

Risposte:


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

Riferimento: Strutture dati> Altro sugli elenchi

Seguono avvertimenti

Si noti che mentre questo è forse il modo più pulito per rispondere alla domanda come posta , indexè un componente piuttosto debole listdell'API e non ricordo l'ultima volta che l'ho usato con rabbia. Mi è stato sottolineato nei commenti che, poiché questa risposta è fortemente referenziata, dovrebbe essere resa più completa. list.indexSeguono alcune avvertenze . Probabilmente vale la pena dare un'occhiata inizialmente alla documentazione per questo:

list.index(x[, start[, end]])

Restituisce l'indice in base zero nell'elenco del primo elemento il cui valore è uguale a x . Genera un ValueErrorse non esiste tale oggetto.

Gli argomenti facoltativi inizio e fine vengono interpretati come nella notazione della sezione e vengono utilizzati per limitare la ricerca a una particolare sottosequenza dell'elenco. L'indice restituito viene calcolato relativamente all'inizio dell'intera sequenza anziché all'argomento iniziale.

Complessità temporale lineare nella lunghezza dell'elenco

Una indexchiamata controlla ogni elemento dell'elenco in ordine, fino a quando non trova una corrispondenza. Se la tua lista è lunga e non sai all'incirca dove si trova nell'elenco, questa ricerca potrebbe diventare un collo di bottiglia. In tal caso, è necessario considerare una struttura dati diversa. Nota che se sai approssimativamente dove trovare la partita, puoi dare indexun suggerimento. Ad esempio, in questo frammento, l.index(999_999, 999_990, 1_000_000)è circa cinque ordini di grandezza più veloce di quello diritto l.index(999_999), perché il primo deve solo cercare 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 della prima corrispondenza nel suo argomento

Una chiamata per indexcercare l'elenco in ordine fino a quando non trova una corrispondenza e si ferma lì. Se si prevede di aver bisogno di indici di più corrispondenze, è necessario utilizzare una comprensione dell'elenco o un'espressione del 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 luoghi in cui una volta avrei usato index, ora uso una comprensione dell'elenco o un'espressione del generatore perché sono più generici. Quindi, se stai pensando di cercare index, dai un'occhiata a queste eccellenti funzionalità di Python.

Genera se l'elemento non è presente nell'elenco

Una chiamata a indexgenera un ValueErrorse l'elemento 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'elemento potrebbe non essere presente nell'elenco, dovresti farlo anche tu

  1. Controllalo prima con item in my_list(approccio pulito e leggibile) o
  2. Avvolgi la indexchiamata in un try/exceptblocco che cattura ValueError(probabilmente più veloce, almeno quando l'elenco da cercare è lungo e l'elemento è solitamente presente).

20
index restituisce il primo elemento il cui valore è "bar". Se "bar" esiste due volte nell'elenco, non troverai mai la chiave per la seconda "bar". Vedi documentazione: docs.python.org/3/tutorial/datastructures.html
mpoletto

2
Se stai cercando solo un elemento (il primo), ho scoperto che index()è poco meno del 90% più veloce della comprensione dell'elenco rispetto agli elenchi di numeri interi.
slybloty,

Quale struttura di dati dovrebbe essere utilizzata se l'elenco è molto lungo?
izhang05,

@izhang: alcuni indici ausiliari, come un dict {element -> list_index}, se gli elementi sono hash, e la posizione nella lista è importante.
Alex Coventry,

899

Una cosa che è veramente utile nell'apprendimento di Python è l'uso della funzione di aiuto 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 spesso ti condurrà al metodo che stai cercando.


2
bpython è un modo semplice e intuitivo per leggere i documenti in modo interattivo.
Goetzc,

@davidavr sì, ma poi il resto di noi che vuole solo cercarlo su Google invece di scorrere tra i documenti di aiuto non avrebbe questo simpatico, centralissimo, ranking set di opzioni. :)
honkaboy

556

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

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

La index()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 dell'enumerazione):

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 elenchi più grandi rispetto all'uso di 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

L'enumerazione funziona meglio dei metodi basati sull'indice per me, dal momento che sto cercando di raccogliere gli indici delle stringhe usando 'startwith "e ho bisogno di raccogliere più occorrenze. Oppure c'è un modo per usare l'indice con" startwith "che non riuscivo a capire
Tupelo Thistlehead,

3
Nelle mie mani, la versione enumerata è costantemente leggermente più veloce. Alcuni dettagli di implementazione potrebbero essere cambiati da quando è stata pubblicata la misurazione sopra.
Alex Coventry,

2
Questo è stato già risposto dal '11: stackoverflow.com/questions/6294179/...
Cristik


132

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"])

2
E se non esiste nell'elenco?
Peter Mortensen,

1
L'elemento inesistente genererà ValueError
Nam G VU il

1
Questa risposta si adatterebbe meglio qui: stackoverflow.com/questions/6294179/...
Cristik

86

Si verificherà un problema se l'elemento non è nell'elenco. 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


58

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

1
Questo ci aiuta a evitare di provare a catturare!
devssh,

Tuttavia, potrebbe raddoppiare la complessità. Qualcuno ha controllato?
Stefanct,

@stefanct La complessità temporale è ancora lineare, ma ripeterà l'elenco due volte.
Approaching

@ApproachingDarknessFish Questo è ovviamente ciò che intendevo. Anche se pedanticamente è lo stesso ordine di complessità, l'iterazione due volte potrebbe essere un grave svantaggio in molti casi d'uso, quindi l'ho sollevato. E ancora non conosciamo la risposta ...
stefanct,

44

Tutte le funzioni proposte qui riproducono comportamenti linguistici intrinseci 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?


9
Il terzo metodo scorre due volte nell'elenco, giusto?
Eric Duminil,

Ri: "Tutte le funzioni proposte qui" : Forse al momento in cui scrivo, ma dovresti controllare le risposte più recenti per vedere se è ancora vero.
Peter Mortensen,

41

Se vuoi tutti gli indici, 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.


4
Che dire di elenchi di stringhe, elenchi di oggetti non numerici, ecc ...?
Laryx Decidua,

1
Questa risposta dovrebbe essere meglio postato qui: stackoverflow.com/questions/6294179/...
Cristik

1
Questo è il migliore che abbia letto. gli array intorpiditi sono molto più efficienti degli elenchi Python. Se l'elenco è breve, non è un problema crearne una copia da un elenco Python, in caso contrario lo sviluppatore dovrebbe prendere in considerazione l'idea di archiviare gli elementi nell'array numpy in primo luogo.
Athanassios,

35

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

Per un elenco ["foo", "bar", "baz"]e un elemento nell'elenco "bar", qual è il modo più pulito per ottenere il suo indice (1) in Python?

Bene, certo, c'è il metodo index, che restituisce l'indice della prima occorrenza:

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

Esistono un paio di problemi con questo metodo:

  • se il valore non è presente nell'elenco, otterrai a ValueError
  • se nell'elenco è presente più di un valore, viene visualizzato solo l'indice per il primo

Nessun valore

Se il valore potrebbe mancare, è necessario catturare il ValueError.

Puoi farlo con una definizione riutilizzabile come questa:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

E usalo in questo modo:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

E il rovescio della medaglia di questo è che probabilmente avrai un controllo per se il valore restituito iso is notNessuno:

result = index(a_list, value)
if result is not None:
    do_something(result)

Più di un valore nell'elenco

Se potessi avere più ricorrenze, non otterrai informazioni complete con list.index:

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

È possibile elencare in un elenco di comprensione degli indici:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

Se non si verificano occorrenze, è possibile verificarlo con un controllo booleano del risultato o semplicemente non fare nulla se si passa in rassegna i risultati:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

Munging di dati migliori con i panda

Se hai i panda, puoi facilmente ottenere queste informazioni con un oggetto Series:

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

Un controllo comparativo restituirà una serie di booleani:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

Passa quella serie di booleani alla serie tramite notazione in pedice e otterrai solo i membri corrispondenti:

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

Se vuoi solo gli indici, l'attributo index restituisce una serie di numeri interi:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

E se li vuoi in un elenco o tupla, passali al costruttore:

>>> list(series[series == 'bar'].index)
[1, 3]

Sì, potresti usare anche una comprensione dell'elenco con enumerate, ma secondo me non è così elegante - stai facendo dei test per l'uguaglianza in Python, invece di lasciare che il codice incorporato scritto in C lo gestisca:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

È un problema XY ?

Il problema XY è chiedere la tua soluzione tentata piuttosto che il tuo problema reale.

Perché pensi di aver bisogno dell'indice dato un elemento in un elenco?

Se conosci già il valore, perché ti importa dove si trova in un elenco?

Se il valore non è presente, la cattura ValueErrorè piuttosto dettagliata - e preferisco evitarlo.

Di solito sto ripetendo l'elenco, quindi di solito terrò un puntatore a qualsiasi informazione interessante, ottenendo l' indice con enumerato.

Se stai mungendo i dati, dovresti probabilmente usare i panda, che hanno strumenti molto più eleganti dei semplici soluzioni Python che ho mostrato.

Non ricordo di aver bisogno di list.indexme stesso. Tuttavia, ho esaminato la libreria standard di Python e ne vedo alcuni eccellenti usi.

Ci sono molti, molti usi per esso in idlelib, per la GUI e l'analisi del testo.

Il keywordmodulo lo utilizza per trovare marcatori di commento nel modulo per rigenerare automaticamente l'elenco di parole chiave in esso tramite metaprogrammazione.

In Lib / mailbox.py sembra usarlo come una mappatura ordinata:

key_list[key_list.index(old)] = new

e

del key_list[key_list.index(key)]

In Lib / http / cookiejar.py, sembra essere usato per ottenere il mese successivo:

mon = MONTHS_LOWER.index(mon.lower())+1

In Lib / tarfile.py simile a distutils per ottenere una sezione fino a un elemento:

members = members[:members.index(tarinfo)]

In Lib / pickletools.py:

numtopop = before.index(markobject)

Ciò che questi usi sembrano avere in comune è che sembrano operare su elenchi di dimensioni vincolate (importante a causa del tempo di ricerca O (n) per list.index), e sono principalmente usati nell'analisi (e nell'interfaccia utente nel caso di Idle).

Mentre ci sono casi d'uso per questo, sono abbastanza rari. Se ti trovi in ​​cerca di questa risposta, chiediti se quello che stai facendo è l'uso più diretto degli strumenti forniti dalla lingua per il tuo caso d'uso.



21

Ottenere tutte le occorrenze e la posizione di uno o più elementi (identici) in un elenco

Con enumerate (alist) puoi memorizzare il primo elemento (n) che è l'indice dell'elenco quando l'elemento x è uguale a quello che cerchi.

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

Facciamo trovare la nostra funzione findindex

Questa funzione prende l'oggetto e l'elenco come argomenti e restituisce la posizione dell'oggetto nell'elenco, come abbiamo visto prima.

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

Produzione


[1, 3, 5, 7]

Semplice

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

Produzione:

0
4

1
Questa risposta dovrebbe essere meglio postato qui: stackoverflow.com/questions/6294179/...
Cristik

16

Semplicemente puoi andare con

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']

res = [[x[0] for x in a].index(y) for y in b]

16

Un'altra opzione

>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
...     indices.append(a.index(b,offset))
...     offset = indices[-1]+1
... 
>>> indices
[0, 3]
>>> 

1
Questa risposta dovrebbe essere meglio postato qui: stackoverflow.com/questions/6294179/...
Cristik

15

E ora qualcosa di completamente diverso...

... come confermare l'esistenza dell'articolo prima di ottenere l'indice. La cosa bella di questo approccio è che la funzione restituisce sempre un elenco di indici, anche se è un elenco vuoto. Funziona anche con le stringhe.

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    retval = []
    last = 0
    while val in l[last:]:
            i = l[last:].index(val)
            retval.append(last + i)
            last += i + 1   
    return retval

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

Quando incollato in una finestra interattiva di Python:

Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(the_list, val):
...     """Always returns a list containing the indices of val in the_list"""
...     retval = []
...     last = 0
...     while val in the_list[last:]:
...             i = the_list[last:].index(val)
...             retval.append(last + i)
...             last += i + 1   
...     return retval
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

Aggiornare

Dopo un altro anno di sviluppo di Python a testa in giù, sono un po 'imbarazzato dalla mia risposta originale, quindi per mettere le cose in chiaro, si può certamente usare il codice sopra; tuttavia, il modo molto più idiomatico di ottenere lo stesso comportamento sarebbe utilizzare la comprensione dell'elenco, insieme alla funzione enumerate ().

Qualcosa come questo:

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    return [index for index, value in enumerate(l) if value == val]

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

Che, quando incollato in una finestra interattiva di Python produce:

Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(l, val):
...     """Always returns a list containing the indices of val in the_list"""
...     return [index for index, value in enumerate(l) if value == val]
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

E ora, dopo aver esaminato questa domanda e tutte le risposte, mi rendo conto che questo è esattamente ciò che FMc ha suggerito nella sua precedente risposta . All'epoca in cui avevo inizialmente risposto a questa domanda, non vedevo nemmeno quella risposta, perché non l'avevo capito. Spero che il mio esempio un po 'più dettagliato possa aiutare a capire.

Se la singola riga di codice sopra non ha ancora senso per te, ti consiglio vivamente la "comprensione dell'elenco python" di Google e dedicare qualche minuto a familiarizzare. È solo una delle tante potenti funzionalità che rendono piacevole l'utilizzo di Python per lo sviluppo di codice.


12

Una variante della risposta di FMc e user7177 fornirà un dict che può restituire tutti gli indici per qualsiasi voce:

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

Puoi anche usarlo come una riga per ottenere tutti gli indici per una singola voce. Non ci sono garanzie di efficienza, anche se ho usato set (a) per ridurre il numero di volte in cui viene chiamata lambda.


1
Questa risposta dovrebbe essere meglio postato qui: stackoverflow.com/questions/6294179/...
Cristik

10

Questa soluzione non è potente come le altre, ma se sei un principiante e conosci solo i forloop è comunque possibile trovare il primo indice di un elemento evitando ValueError:

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1

9

Ricerca dell'indice dell'elemento x nell'elenco L:

idx = L.index(x) if (x in L) else -1

4
In questo modo, l'array viene ripetuto due volte, pertanto potrebbero verificarsi problemi di prestazioni per array di grandi dimensioni.
Cristik,

Essere d'accordo. Se le liste sono molto lunghe, sceglierei qualcos'altro. Non dovrebbe essere un grosso problema per gli elenchi di piccole e medie dimensioni.
Ketan,

5

Poiché gli elenchi Python sono basati su zero, possiamo usare la funzione integrata zip come segue:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

dove "pagliaio" è l'elenco in questione e "ago" è l'elemento da cercare.

(Nota: qui stiamo iterando usando i per ottenere gli indici, ma se dobbiamo piuttosto concentrarci sugli elementi possiamo passare a j.)


3
[i for i, j in enumerate (pagliaio) se j == 'ago'] è più compatto e leggibile, credo.
Giovanni G. PY il

5
name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

Questo spiega se anche la stringa non è nell'elenco, se non è nell'elenco allora location = -1


4

Il index()metodo Python genera un errore se l'elemento non è stato trovato. Quindi invece puoi renderlo simile alla indexOf()funzione di JavaScript che restituisce -1se l'elemento non è stato trovato:

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

5
tuttavia, JavaScript ha la filosofia secondo cui risultati strani sono migliori degli errori, quindi ha senso restituire -1, ma in Python può essere difficile rintracciare un bug, poiché -1 restituisce un elemento dalla fine dell'elenco.
Sapphire_Brick,

3

C'è una risposta più funzionale a questo.

list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

Forma più generica:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))

1
Questa risposta è Scala
perfetta per gli

3

Diamo il nome lstall'elenco che hai. Si può convertire la lista lstin a numpy array. E poi usa numpy.where per ottenere l'indice dell'elemento scelto nell'elenco. Di seguito è riportato il modo in cui lo implementerai.

import numpy as np

lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1

2

Per quelli che provengono da un'altra lingua come me, forse con un semplice ciclo è più facile da capire e usarlo:

mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)

Sono grato per cosa fa esattamente l'enumerato? . Questo mi ha aiutato a capire.


2

Se hai intenzione di trovare un indice una volta, allora il metodo "index" va bene. Tuttavia, se hai intenzione di cercare i tuoi dati più di una volta, ti consiglio di utilizzare il modulo bisect . Tenere presente che è necessario ordinare i dati del modulo bisect. Quindi ordina i dati una volta e poi puoi usare bisect. L'uso del modulo bisect sulla mia macchina è circa 20 volte più veloce rispetto all'utilizzo del metodo dell'indice.

Ecco un esempio di codice che utilizza la sintassi di Python 3.8 e successive:

import bisect
from timeit import timeit

def bisect_search(container, value):
    return (
      index 
      if (index := bisect.bisect_left(container, value)) < len(container) 
      and container[index] == value else -1
    )

data = list(range(1000))
# value to search
value = 666

# times to test
ttt = 1000

t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)

print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")

Produzione:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

1

Se le prestazioni sono preoccupanti:

In numerose risposte viene menzionato che il metodo di list.index(item)metodo integrato è un algoritmo O (n). Va bene se devi eseguirlo una volta. Ma se è necessario accedere agli indici degli elementi più volte, è più sensato creare prima un dizionario (O (n)) di coppie oggetto-indice, quindi accedere all'indice su O (1) ogni volta che è necessario esso.

Se sei sicuro che gli elementi nel tuo elenco non vengano mai ripetuti, puoi facilmente:

myList = ["foo", "bar", "baz"]

# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))

# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.

Se potresti avere elementi duplicati e devi restituire tutti i loro indici:

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Lookup
myDict["foo"] # Returns [0, 4]

1

Come indicato da @TerryA, molte risposte discutono su come trovare un indice.

more_itertoolsè una libreria di terze parti con strumenti per individuare più indici all'interno di un iterabile.

Dato

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

Codice

Trova indici di più osservazioni:

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

Prova più elementi:

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

Vedi anche più opzioni con more_itertools.locate. Installa tramite > pip install more_itertools.


0

usando il dizionario, dove prima elabora l'elenco e quindi aggiunge l'indice

from collections import defaultdict

index_dict = defaultdict(list)    
word_list =  ['foo','bar','baz','bar','any', 'foo', 'much']

for word_index in range(len(word_list)) :
    index_dict[word_list[word_index]].append(word_index)

word_index_to_find = 'foo'       
print(index_dict[word_index_to_find])

# output :  [0, 5]

-1

secondo me ["foo", "bar", "baz"].index("bar")va bene ma non è abbastanza! perché se "bar" non è nel dizionario, ValueErrorsollevato . Quindi puoi usare questa funzione:

def find_index(arr, name):
    try:
        return arr.index(name)
    except ValueError:
        return -1

if __name__ == '__main__':
    print(find_index(["foo", "bar", "baz"], "bar"))

e il risultato è:

1

e se il nome non era in arr, la funzione restituisce -1.per esempio:

print (find_index (["foo", "bar", "baz"], "fooo"))

-1


1
Non usarlo perché l = [1, 2]; find_index(l, 3)ritornerebbe -1e l[find_index(l, 3)]ritornerebbe 2. -1 è una cosa negativa da restituire, basta restituire None.
Daniel Stracaboško,

-1 è un contratto che puoi restituire qualsiasi cosa tu voglia, ma cerca di usare Nessuno in meno nei tuoi programmi perché None o Null nella comunicazione del tuo programma con altri programmi come siti Web Android e PHP potrebbero causare l'interruzione del programma, ad esempio potresti restituire null in JSON e l'applicazione del telefono del sito Web verrà chiusa o restituirà l'errore 500 (errore interno del server).
NaabNuts
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.