2009-07-26 24 views
121

Nel mio codice di esempio di seguito, è effettivamente richiesto il contatore = 0 oppure esiste un modo migliore, più Python, per accedere a un contatore di loop? Ho visto alcuni PEP relativi ai contatori di loop, ma erano differiti o rifiutati (PEP 212 e PEP 281).Contatore loop Python in un ciclo for

Questo è un esempio semplificato del mio problema. Nella mia vera applicazione questo è fatto con la grafica e l'intero menu deve essere ridipinto ogni fotogramma. Ma questo lo dimostra in un modo semplice di testo che è facile da riprodurre.

Forse dovrei anche aggiungere che sto usando Python 2.5, anche se sono ancora interessato se esiste un modo specifico per 2.6 o superiore.

# Draw all the options, but highlight the selected index 
def draw_menu(options, selected_index): 
    counter = 0 
    for option in options: 
     if counter == selected_index: 
      print " [*] %s" % option 
     else: 
      print " [ ] %s" % option 
     counter += 1 


options = ['Option 0', 'Option 1', 'Option 2', 'Option 3'] 

draw_menu(option, 2) # Draw menu with "Option2" selected 

Quando viene eseguito, esso emette:

[ ] Option 0 
[ ] Option 1 
[*] Option 2 
[ ] Option 3 
+0

si può semplicemente utilizzare la proprietà length matrice invece del per in loop metodo, per i Jim

+2

possibile duplicato di [Accesso all'indice in Python per cicli] (http://stackoverflow.com/questions/522563/accessing-the-index-in-python-for-loops) –

risposta

214

Usa enumerate() in questo modo:

def draw_menu(options, selected_index): 
    for counter, option in enumerate(options): 
     if counter == selected_index: 
      print " [*] %s" % option 
     else: 
      print " [ ] %s" % option  

options = ['Option 0', 'Option 1', 'Option 2', 'Option 3'] 
draw_menu(options, 2) 

Nota: Opzionalmente si può mettere tra parentesi intorno counter, option, come (counter, option), se vuoi, ma sono estranei e normalmente non in cluso.

4

Si potrebbe anche fare:

for option in options: 
     if option == options[selected_index]: 
      #print 
     else: 
      #print 

Anche se ci si esegue in problemi se ci sono opzioni duplicati.

+4

Oppure se le opzioni sono un iteratore. –

4

farò a volte fare questo:

def draw_menu(options, selected_index): 
    for i in range(len(options)): 
     if i == selected_index: 
      print " [*] %s" % options[i] 
     else: 
      print " [ ] %s" % options[i] 

Anche se tendo a evitare questo se questo significa sarò dicendo più options[i] di un paio di volte.

+5

In tal caso dovresti sempre usare enumerate() –

+0

g, e se hai bisogno di ottenere l'elemento ogni tanto, ma hai bisogno dell'indice ogni volta? Sembra che in quelle situazioni questo potrebbe essere utile perché non si sta creando una nuova variabile ogni volta. –

+1

@gs: sì. Questa risposta era già stata pubblicata, quindi stavo pubblicando una soluzione alternativa. Come al solito, quale risposta è la migliore dipende dai dettagli della tua situazione. –

0

enumerate è quello che stai cercando.

Potreste anche essere interessati a unpacking:

# The pattern 
x, y, z = [1, 2, 3] 

# also works in loops: 
l = [(28, 'M'), (4, 'a'), (1990, 'r')] 
for x, y in l: 
    print(x) # prints the numbers 28, 4, 1990 

# and also 
for index, (x, y) in enumerate(l): 
    print(x) # prints the numbers 28, 4, 1990 

Inoltre, v'è itertools.count() Così si potrebbe fare qualcosa di simile

import itertools 

for index, el in zip(itertools.count(), [28, 4, 1990]): 
    print(el) # prints the numbers 28, 4, 1990