【问题标题】:Looking for an elegant way to `time.sleep()` after every iteration, except the last iteration在每次迭代后寻找一种优雅的方式来“time.sleep()”,除了最后一次迭代
【发布时间】:2018-03-17 04:11:58
【问题描述】:

我有一个物品清单:list = [a, b, c, d] 我想修改每个项目,然后time.sleep(10),然后再进行下一次迭代。在最后一次迭代中,我想修改项目,但要避免睡觉。

for item in list:  
    # modify item  
    time.sleep(10) # avoid this line on the final iteration  

不必是这种结构——寻找任何可以完成工作的方法。

【问题讨论】:

    标签: python python-2.7 python-3.x for-loop


    【解决方案1】:

    您可以先睡眠,但在第一次迭代睡眠时跳过睡眠,而是:

    for idx, item in enumerate(list):
        if idx != 0:   
            time.sleep(10) # avoid this line on the final iteration 
        # modify item 
    

    它在最后一项掉下来,没有睡觉。

    【讨论】:

      【解决方案2】:

      另一个使用enumerate的解决方案:

      lst = ['a', 'b', 'c', 'd']
      for i, v in enumerate(lst, 1 - len(lst)):
          print(v)
          if i:
              print('sleeping')
      

      输出

      a
      sleeping
      b
      sleeping
      c
      sleeping
      d
      

      【讨论】:

      • 如果我理解正确,您将传递 -3 作为枚举的起始索引,以进行迭代:-3、-2、-1、0,并将 0 用作 @ 的 False 987654324@声明?
      • @Simonsays 是的,没错。在 Python 中,零是 False-ish,非零数字是 True-ish。
      【解决方案3】:

      如果您反转问题并添加一个布尔值来表示第一个元素,您可以这样做:

      do_sleep = False
      for item in list:  
          if do_sleep:
              time.sleep(10) # avoid this line on the first iteration.
          else:
              do_sleep = True
          # modify item  
      

      【讨论】:

      • 很好发现!谢谢,已修复。
      【解决方案4】:

      您可以使用enumerate 来跟踪索引:

      for index, data in enumerate(list, 1 - len(list)):
          if index: 
              time.sleep(10)
      

      【讨论】:

      • 1 你可以传递enumerate 一个起始值。 2 为什么要在每次循环迭代时计算列表长度?它不会改变(至少,我认为它不会改变,因为改变你正在迭代的列表的长度通常是不明智的,除非你非常小心)。当然,获取列表长度是一个非常快的操作,但仍然......
      • @PM2Ring 啊,谢谢指出,我应该使用enumerate(list, 1 - len(list))
      • 但这正是你写的@PM2Ring。顺便说一句,感谢您提到 2 点(它们真的很有帮助)对我来说是一个学习
      【解决方案5】:

      如果您想避免在每次迭代中测试最后一个元素。

      for element in elements[:-1]:
          process_element(element)
          time.sleep(10)
      
      process_element(element)
      

      如果需要将更改应用于列表中的元素(无需创建新元素)。

      for index, _ in enumerate(elements[:-1]):
          process_element(elements, index)
          time.sleep(10)
      
      process_element(elements, -1)
      
      def process_element(elements, index):
          elements[index] += 1
      

      如果您想避免复制列表,您可以使用islice。请注意,len([]) 的成本为 O(1)。

      for element in islice(elements, len(elements) - 1):
          ...
      
      for index, _ in enumerate(islice(elements, len(elements) - 1)):
          ...
      

      【讨论】:

      • 这不会完全跳过修改最后一项吗?
      • islice 方法可以处理引用副本。
      • @Simonsays 最后一项在循环外处理。
      • 修改答案以支持@Simonsays 用例。
      • 答案通过就地修改和迭代完成,而不是切片(复制)。
      【解决方案6】:
      for i,item in enumerate(list):
          # modify item
          if i < len(list) - 1:
              time.sleep(10)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-23
        相关资源
        最近更新 更多