【问题标题】:Iterate a certain number of times without storing the iteration number anywhere [duplicate]迭代一定次数而不将迭代次数存储在任何地方[重复]
【发布时间】:2011-04-10 19:14:35
【问题描述】:

我想知道是否可以在不将循环迭代数存储在任何地方的情况下执行一定数量的操作。

例如,假设我想将两条"hello" 消息打印到控制台。现在我知道我可以做到:

for i in range(2):
    print "hello"

但是i 变量将采用01 的值(我并不真正需要)。有没有办法在不将那些不需要的值存储在任何地方的情况下实现相同的目标?

不用说,使用变量并不是什么大问题...我只是好奇。

【问题讨论】:

    标签: python loops range


    【解决方案1】:

    你可以这样做

    print 2*'hello'
    

    【讨论】:

    • 这只是 example OP 提供的解决方案。它不会回答所有实例。
    【解决方案2】:

    这将打印 'hello' 3 次而不存储 i...

    [print('hello') for i in range(3)]
    

    【讨论】:

    • 这与 OP 的原始代码相同,只是作为列表理解而不是 for 循环呈现。
    • 我认为 i 不会存在于列表理解之外,这与 for 循环不同
    • @SamHartman:i 将存在于 Py2 上的 listcomp 之外,但不在 Py3 上。列表推导在 Py2 上没有单独的作用域,但在 Py3(以及 Py2 上的 genexprs 和 setcomp/dictcomps)中,它们在闭包作用域中运行,其中迭代变量是闭包作用域的本地变量,并且在它之外无法看到。 listcomps 和所有其他理解/genexprs 之间的差异是 Py2 和 Py3 之间简化(以破坏兼容性的方式)的事情之一。
    【解决方案3】:

    其他人已经解决了在for 循环中无法完全避免迭代变量的问题,但是有一些选项可以减少少量工作。 range 毕竟要生成一大堆数字,这涉及的工作量很小;如果您想避免这种情况,您可以使用itertools.repeat 一遍又一遍地获取相同(忽略)的值,这不涉及创建/检索不同的对象:

    from itertools import repeat
    
    for _ in repeat(None, 200):  # Runs the loop 200 times
        ...
    

    这将在微基准测试中比for _ in range(200): 运行得更快,但如果循环体做了有意义的工作,那就是杯水车薪了。与为您的循环可迭代乘以一些匿名序列不同,repeat 的设置成本微不足道,并且没有依赖于长度的内存开销。

    【讨论】:

      【解决方案4】:

      好吧,我认为您在问题中提供的 forloop 已经差不多了,但我想指出,必须分配的未使用变量可以分配给名为 _ 的变量,这是一个约定用于“丢弃”分配的值。尽管_ 引用将保留您给它的值,但代码检查器和其他开发人员会理解您没有使用该引用。所以这里有一个例子:

      for _ in range(2):
          print('Hello')
      

      【讨论】:

        【解决方案5】:

        抱歉,为了迭代任何语言(包括 Python 和英语)的任何内容,必须存储索引。无论是否在变量中。找到一种方法来掩盖 python 在内部跟踪 for 循环这一事实不会改变它的事实。我建议保持原样。

        【讨论】:

          【解决方案6】:
          exec 'print "hello";' * 2
          

          应该可以,但我有点惭愧,我想到了它。

          更新:刚刚想到另一个:

          for _ in " "*10: print "hello"
          

          【讨论】:

          • 为你的诚实+1 ;-)
          【解决方案7】:

          虽然我完全同意delnan的回答,但也不是不可能:

          loop = range(NUM_ITERATIONS+1)
          while loop.pop():
              do_stuff()
          

          但是请注意,这不适用于任意列表:如果列表中的第一个值(弹出的最后一个值)的计算结果不为 False,您将在下一次遍历中获得另一个迭代和异常:IndexError: pop from empty list。此外,循环后您的列表 (loop) 将为空。

          只是为了好奇。 ;)

          【讨论】:

            【解决方案8】:
            for word in ['hello'] * 2:
                print word
            

            这不是惯用的 Python,但也不是你想要做的。

            【讨论】:

            • 例如,您需要一个未使用的变量来生成随机数列表。
            • 问题是,变量实际上并没有被使用。有人必须跟踪迭代多少次,以及循环执行了多少次。
            • @Nathon:错了。由于for i in seq: stuff() 等价于(请原谅我使用大括号,但 cmets 不会阻止换行)_iterator = iter(seq); while True { try { i = next(_iterator) } except StopIteration { break } stuff() },因此我们可以从脱糖版本中删除 i = 部分并最终没有迭代变量。所有迭代状态都由迭代器管理,而不是由迭代变量管理。
            • @delnan 我的意思是内心深处。实现仍然需要跟踪(即使它隐藏在迭代器类的某个地方)。总会有一些内存专门用于跟踪我们在迭代中的位置。它可能无法访问,但这并不意味着它不存在。
            • @nmichaels:即使在 CPU 寄存器的内部,您也可以在不隐藏迭代变量的情况下进行迭代,例如 def g(): { while True: { if random.random() < 0.1: { break } else { yield 1 } } }g() 是一个生成器;在任何给定时间,迭代停止并且没有任何迭代变量的可能性为 10就外部源而言,例如random.org 在这种情况下,没有什么可以预测迭代何时停止)
            【解决方案9】:

            未使用变量的习惯用法(由许多其他语言共享)是一个下划线_。代码分析器通常不会抱怨_ 未被使用,程序员会立即知道它是i_dont_care_wtf_you_put_here 的快捷方式。如果没有 item 变量,就无法进行迭代——正如 Python 之禅所说,“特殊情况不足以打破规则”。

            【讨论】:

            • 我不明白为什么像 AutoHotkey 的 Loop, 5 { ... 这样的东西(只需重复一个动作 5 次)在其他任何地方都不存在。不需要变量,提供更好的可读性。
            • _ 也用于gettext i18n 及其解释器预定义变量。 i 看起来好多了
            • @phil294 我想有时如果你在重构,你可能需要这个变量,所以改变它的名字比改变整个循环更容易。
            猜你喜欢
            • 2013-05-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-28
            • 2021-10-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多