Come ottenere la posizione dell'articolo in un elenco?


169

Sto ripetendo un elenco e voglio stampare l'indice dell'articolo se soddisfa una determinata condizione. Come lo farei?

Esempio:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position

Risposte:


280

Hmmm. C'è stata una risposta con una comprensione dell'elenco qui, ma è scomparsa.

Qui:

 [i for i,x in enumerate(testlist) if x == 1]

Esempio:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

Aggiornare:

Ok, vuoi un'espressione di generatore, avremo un'espressione di generatore. Ecco di nuovo la comprensione dell'elenco, in un ciclo for:

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

Ora costruiremo un generatore ...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

e abbastanza saggiamente, possiamo assegnarlo a una variabile e usarlo da lì ...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

E pensare che scrivevo FORTRAN.


6
Dopo probabilmente 25 anni di domande sulla programmazione funzionale, penso di aver finalmente capito. la comprensione dell'elenco è da bomba.
Charlie Martin,

15
Presumo che tu intenda "singola lettera" e, francamente, un nome più lungo in questo esempio non avrebbe più contenuto informativo.
Charlie Martin,

2
Grazie per l'ottima risposta. Penso che il commento di @ nailer possa essere correlato al fatto che usi 'i' in due contesti diversi in una sola riga nell'esempio del generatore; uno all'interno della comprensione e l'altro per iterare attraverso di essa. So che mi ha lasciato senza parole per un secondo.
Brown,

1
@CharlieMartin Si utilizza 'i' per l'indice anziché l'elemento secondo la convenzione comune per le variabili a carattere singolo. La denominazione dell'indice "indice" e dell'elemento "oggetto" eliminerebbe l'ambiguità. Inoltre stai rispondendo a un genitore che ha usato 'item' e 'position' ed è buona norma non rinominare inutilmente parti del codice originale nella tua risposta.
mikemaccana,

1
Super sintassi: o) È possibile ottenere facilmente un parametro della riga di comando. Lasciate che v'è una serie di argomenti: args = ['x', '-p1', 'v1', '-p2', 'v2']. Quindi il comando args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]ritorna'v1'
Theodor Keinstein il

170

Che dire di quanto segue?

print testlist.index(element)

Se non sei sicuro che l'elemento da cercare sia effettivamente nell'elenco, puoi aggiungere un controllo preliminare, ad esempio

if element in testlist:
    print testlist.index(element)

o

print(testlist.index(element) if element in testlist else None)

o il "modo pitonico", che non mi piace tanto perché il codice è meno chiaro, ma a volte è più efficiente,

try:
    print testlist.index(element)
except ValueError:
    pass

5
invece di testare prima di accedere, potresti anche provare e verificareValueError
kratenko il

Penso che voglia trovare tutte le occorrenze, sembra che tu ne dia solo la prima.
tfv

@tfv Non vedo come puoi arrivare a tale conclusione poiché la domanda dice "item" e non "items".
mmj,

40

Usa enumerare:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange invece di range come richiesto (vedi commenti).


sostituisci range () con xrange () - range () crea un elenco, xrange () crea un iteratore. xrange () usa waaaay meno memoria e la chiamata iniziale è più veloce.
Gnud,

2
Sono d'accordo per elenchi di grandi dimensioni nei programmi Python 2. Nota che 'range' funzionerà comunque in Python 3 (e funzionerà come xrange IIRC). 'xrange' sta andando sulla strada dei dinosauri.
jakber,

2
Aggiornamento: xrangeè depresso in Python 3.x, poiché il nuovo rangeè il vecchioxrange
tim-oh

5

Ecco un altro modo per farlo:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"


2

Prova il seguente:

testlist = [1,2,3,5,3,1,2,1,6]    
position=0
for i in testlist:
   if i == 1:
      print(position)
   position=position+1

1

Se l'elenco è diventato abbastanza grande e ti aspettavi di trovare il valore in un numero limitato di indici, considera che questo codice potrebbe essere eseguito molto più velocemente perché non devi ripetere tutti i valori dell'elenco.

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

Se ti aspetti di trovare molto il valore, probabilmente dovresti semplicemente aggiungere "indice" a un elenco e stampare l'elenco alla fine per risparmiare tempo per ogni iterazione.


Ho fatto alcuni test di cronometraggio. La tecnica di comprensione dell'elenco è più veloce del 38% rispetto a questo codice. (Ho sostituito la tua dichiarazione di stampa con un outputlist.append call)
Deestan,

Ho anche fatto alcuni test con dimensioni di elenco di 100000 valori casuali tra 1 e 100. Il codice che ho scritto era in alcuni casi due volte più veloce. Nessun test del tempo è paragonabile all'applicazione del poster (devono essere testati per essere sicuri, ovviamente). Mi scuso se la mia opinione è stata dannosa per questo post.

0

Penso che potrebbe essere utile utilizzare il metodo curselection () dalla libreria Tkinter:

from Tkinter import * 
listbox.curselection()

Questo metodo funziona sui widget della casella di riepilogo di Tkinter, quindi dovrai costruirne uno anziché un elenco.

Questo restituirà una posizione come questa:

('0',) (anche se le versioni successive di Tkinter potrebbero invece restituire un elenco di ints)

Quale è per la prima posizione e il numero cambierà in base alla posizione dell'oggetto.

Per ulteriori informazioni, consultare questa pagina: http://effbot.org/tkinterbook/listbox.htm

Saluti.


1
Idea interessante. Poiché ciò richiede l'importazione dell'intera libreria Tkinter, tuttavia, non è il modo più efficiente per risolvere il problema.
seaotternerd,

3
Questo è un percorso così inefficiente e tortuoso che direi che è una risposta sbagliata, anche se in qualche modo affronta la domanda.

Questa risposta non ha nulla a che fare con la domanda.
Cody Piersall,

0

Perché complicare le cose?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

0

Giusto per illustrare un esempio completo insieme al input_listquale ha searies1(esempio: input_list [0]) in cui si desidera series2cercare (esempio: input_list [1]) e ottenere indici di serie2 se esiste in serie1.

Nota: certain conditionandrai nell'espressione lambda se le condizioni sono semplici

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

produzione:

[0, 2, 6]

-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

Immagino che sia esattamente quello che vuoi. ;-) 'id' sarà sempre l'indice dei valori nell'elenco.

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.