【问题标题】:Python loop counter in a for loop [duplicate]for循环中的Python循环计数器[重复]
【发布时间】:2010-11-14 04:58:07
【问题描述】:

在下面的示例代码中,是否真的需要 counter = 0,或者是否有更好、更多 Python 的方法来访问循环计数器?我看到了一些与循环计数器相关的 PEP,但它们要么被推迟,要么被拒绝(PEP 212PEP 281)。

这是我的问题的简化示例。在我的实际应用程序中,这是通过图形完成的,并且必须在每一帧重新绘制整个菜单。但这以一种易于复制的简单文本方式展示了它。

也许我还应该补充一点,我正在使用 Python 2.5,尽管我仍然对是否有特定于 2.6 或更高版本的方法感兴趣。

# 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

运行时输出:

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

【问题讨论】:

  • 你可以简单地使用数组长度属性而不是for in循环方法吗,for i

标签: loops for-loop python


【解决方案1】:

enumerate 就是你要找的东西。

你可能也对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

另外,还有itertools.count(),所以你可以做类似的事情

import itertools

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

【讨论】:

    【解决方案2】:

    像这样使用enumerate()

    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)
    

    注意:如果需要,您可以选择在counter, option 周围加上括号,例如(counter, option),但它们是无关的,通常不包括在内。

    【讨论】:

      【解决方案3】:

      我有时会这样做:

      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]
      

      虽然我倾向于避免这种情况,如果这意味着我会多次说options[i]

      【讨论】:

      • 在这种情况下,您应该始终使用 enumerate()
      • gs,如果你只需要偶尔获取元素,但每次都需要索引怎么办?在这些情况下,这似乎是有益的,因为您不是每次都创建一个新变量。
      • @gs:是的。该答案已经发布,所以我发布了一个替代解决方案。像往常一样,哪个答案最好取决于您的具体情况。
      • @EvanFosmark - 两者之间绝对没有性能差异。我检查了以下两个:python -m timeit "s = 'String used for testing'; ''.join(str(i)+str(c) for i, c in enumerate(s))"python -m timeit "s = 'String used for testing'; ''.join(str(i)+str(s[i]) for i in xrange(len(s)))"。在 100,000 次循环中,每个循环的平均时间为 8.83 微秒。其他测试(评论太长)显示 xrange(len(s)) 如果只需要每 16 次迭代访问该元素,则速度非常轻微(~2%)。
      【解决方案4】:

      你也可以这样做:

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

      虽然如果有重复的选项,你会遇到问题。

      【讨论】:

      • 或者如果 options 是一个迭代器。
      猜你喜欢
      • 2020-10-18
      • 2018-11-04
      • 2017-04-16
      • 1970-01-01
      • 2017-02-12
      • 2014-10-09
      • 1970-01-01
      • 2011-03-10
      相关资源
      最近更新 更多