【问题标题】:Execute statement every N iterations in Python在 Python 中每 N 次迭代执行一次语句
【发布时间】:2011-08-03 10:31:28
【问题描述】:

我有一个很长的循环,我想每 N 次迭代检查一次状态,在我的特定情况下,我有一个包含 1000 万个元素的循环,我想每百万次迭代打印一份简短报告。

所以,目前我正在做的只是(n 是迭代计数器):

if (n % 1000000==0):
    print('Progress report...')

但我担心我会通过计算每次迭代的模数来减慢这个过程,因为一次迭代只持续几毫秒。

有没有更好的方法来做到这一点?或者我不应该担心模运算?

【问题讨论】:

    标签: python loops


    【解决方案1】:

    当你达到想要的数字时,保留一个计数器并将其重置为零怎么样?添加和检查相等性比取模更快。

    printcounter = 0
    
    # Whatever a while loop is in Python
    while (...):   
        ...
        if (printcounter == 1000000):
            print('Progress report...')
            printcounter = 0
        ...
        printcounter += 1
    

    虽然编译器很可能已经为您进行了类似的优化......但这可能会让您安心。

    【讨论】:

    • 谢谢,这看起来是最好的解决方案,但我知道我应该真正分析代码以获得明确的答案。
    • 这是一件很容易想到的事情,只有当你知道你可以做这样的事情时:-) 很好的答案,帮助了我两次。
    【解决方案2】:

    喂,老兄?如果您需要其他评论/解释,请联系我:

    1。 xn 的人类语言声明:

    设 x 为在给定时间检查的迭代次数。 让 n 是您的代码将执行的迭代的倍数。

    2。我们在做什么:

    第一个代码块(块 A)仅使用一个变量 x(上面定义),并且使用 5(整数)而不是变量 n(上面定义)。

    第二个代码块(块 B) 使用上面定义的两个变量(x 和 n)。整数 5 将被变量 n 替换。因此,块 B 确实执行一个动作在每次第 n 次迭代

    我们的目标是每第 x 次迭代和每 5/n 次迭代做一些事情。 我们正在经历 100 次迭代。

    米。通俗易懂的代码:

    块 A,最小变量:

    for x in 100:
        #what to do every time (100 times): replace this line with your every-iteration functions.
        if x % 5 == 0:
            #what to do every 5th time: replace this line with your nth-iteration functions.
    

    块 B,概括。

    n = 5
    for x in 100:
        #what to do every time (100 times): replace this line with your every-iteration functions.
        if x % n == 0:
            #what to do every 5th time: replace this line with your nth-iteration functions.
    

    如果您有任何问题,请告诉我,因为我在这里写完之后没有时间测试它。

    3。练习

    1. 如果您已正确完成此操作,请查看是否可以将其与 turtle.Pen() 和 turtle.forward() 函数一起使用。
    2. 看看您是否可以将此程序与 turtle.circle() 函数一起使用。
    3. 查看阅读材料(如下所示),尝试改进练习 1 和 2 中的程序。

    关于模数和其他基本运算符: https://docs.python.org/2/library/stdtypes.html http://www.tutorialspoint.com/python/python_basic_operators.htm

    关于乌龟: https://docs.python.org/2/library/turtle.html https://michael0x2a.com/blog/turtle-examples

    【讨论】:

      【解决方案3】:

      真的慢下来了吗?你必须亲自尝试看看。这不会有太大的放缓,但如果我们谈论的是纳秒,它可能会相当大。或者,您可以将一个 1000 万个循环转换为两个较小的循环:

      m = 1000000
      for i in range(10):
          for i in range(m):
              // do sth
          print("Progress report")
      

      【讨论】:

      • 谢谢,很好的解决方案,如果总长度是报告长度的倍数,这个更好,AndrewKS的回答更笼统。
      【解决方案4】:

      如果不进行测试,很难知道您的系统将如何优化您的代码。

      您可以通过意识到零被评估为假来简化关系部分。

      if(not N % 10000000)
         do stuff
      

      【讨论】:

        【解决方案5】:

        类似的东西? :

        for n in xrange(1000000,11000000,1000000):
            for i in xrange(n-1000000,n):
                x = 10/2
            print 'Progress at '+str(i)
        

        结果

        Progress at 999999
        Progress at 1999999
        Progress at 2999999
        Progress at 3999999
        Progress at 4999999
        Progress at 5999999
        Progress at 6999999
        Progress at 7999999
        Progress at 8999999
        Progress at 9999999
        

        .

        编辑

        更好:

        for n in xrange(0,10000000,1000000):
            for i in xrange(n,n+1000000):
                x = 10/2
            print 'Progress at '+str(i)
        

        灵感来自 pajton:

        m = 1000000
        for n in xrange(0,10*m,m):
            for i in xrange(n,n+m):
                x = 10/2
            print 'Progress at '+str(i+1)
        

        我更喜欢这个,我发现它比 pajton 的解决方案更具可读性。 它根据 i

        保持显示值

        【讨论】:

          【解决方案6】:

          我会做一些测试,看看你的模数调用消耗了多少时间。您可以为此使用timeit。如果您的结果表明需要减少时间,另一种消除模数计算的方法:

          for m in xrange(m_min, m_max):
              for n in xrange(n_min, n_max):
                  #do_n_stuff
              print('Progress report...')
          

          【讨论】:

          • 这个。答案是“在没有首先确定确实有需要的情况下永远不要优化”。
          【解决方案7】:

          它足够快,我不会担心它。

          如果你真的想加快速度,你可以这样做来避免模数

          if (n == 1000000):
              n = 0
              print('Progress report...')
          

          【讨论】:

            【解决方案8】:

            这使得内部循环变得精简,并且m 不必被interval 整除。

            m = 10000000
            interval = 1000000
            i = 0
            while i < m:
                checkpoint = min(m, i+interval)
                for j in xrange(i, checkpoint):
                    #do something
                i = checkpoint
                print "progress"
            

            【讨论】:

              【解决方案9】:

              当我根据计数迭代进行计时/报告时,我只需将我的计数器除以所需的迭代并确定结果是否为整数。所以:

                  if n/1000000 == int(n/1000000):
                      print(report)
              

              【讨论】:

                最近更新 更多