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 14 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.
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.
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.
1enumerate 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