In my example code below, is the counter = 0 really required, or is there a better, more Python, way to get access to a loop counter? I saw a few PEPs related to loop counters, but they were either deferred or rejected (PEP 212 and PEP 281).

This is a simplified example of my problem. In my real application this is done with graphics and the whole menu has to be repainted each frame. But this demonstrates it in a simple text way that is easy to reproduce.

Maybe I should also add that I'm using Python 2.5, although I'm still interested if there is a way specific to 2.6 or higher.

# 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 

When run, it outputs:

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

4 Answers

Use enumerate() like so:

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) 

Note: You can optionally put parenthesis around counter, option, like (counter, option), if you want, but they're extraneous and not normally included.

0

I'll sometimes do this:

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] 

Though I tend to avoid this if it means I'll be saying options[i] more than a couple of times.

4

You could also do:

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

Although you'd run into issues if there are duplicate options.

1

enumerate is what you are looking for.

You might also be interested in 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 

Also, there is itertools.count() so you could do something like

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