3

我有

for i in xrange(repeat):
  #does my stuff
  time.sleep(10)

但是,如果这是最后一次运行,我不希望它睡觉。意思是,如果没有更多的迭代,不要睡觉

我该如何优雅地处理这个?

4

4 回答 4

5
case of 1x repetition: doStuff
case of 2x repetition: doStuff, sleep, doStuff
case of 3x repetition: doStuff, sleep, doStuff, sleep, doStuff
...

你似乎想要做一堆事情,然后在每件事之间睡觉。

此外,延迟与任务的性质无关。


解决方案 1——如果不是最后一个就休眠

最简单的方法是对 for 循环进行特殊处理:

for i in range(numTimesToRepeat):
    if i>0:
        time.sleep(lengthToSleep)
    doStuff()

您也可以执行以下操作,但由于您重复,它就不那么优雅了doStuff()

doStuff()
for i in range(numTimesToRepeat-1):
    time.sleep(lengthToSleep)
    doStuff()

解决方案 2 -- 带 break 的 While 循环

解决这些问题最直接的方法之一是跳出 while 循环。它很脏,而且有点非函数式编程,但这是人类自然会想到的问题:

numTimesToRepeat = ...
while True:
    doStuff()                     # we did stuff
    numTimesToRepeat -= 1         # repeat one less time because we just did it
    if numTimesToRepeat==0:       # do we repeat again?
        break                     #   no -> done!
    else:
        time.sleep(lengthToSleep) #   yes -> sleep before repeating

虽然循环很烦人,因为如果您犯了编程错误,您的程序将无限循环。


解决方案 3 -- 检测是否最后

如果不是循环的第一次迭代,上述方法会做一些事情。但是,“检测循环的最后一次迭代”是您尝试解决问题的方式。这有点烦人,但你可以这样做:https ://stackoverflow.com/a/6090673/711085并像这样使用它:

for i,task,isLast in enumerateLast(tasks):
    task()
    if not isLast:
        time.sleep(lengthToSleep)

不太优雅的是反转列表并执行以下操作enumerate()

for untilLast,task in reversed(enumerate(reversed(tasks))):
    task()
    if untilLast>0:
        time.sleep(lengthToSleep)

(非常小的无关细节:请注意,在这种reversed(enumerate(reversed(iterable)))情况下,如果任务是一个生成器,它将生成每个要执行的任务,以相反的顺序枚举它们,然后执行它们:这可能会导致滞后,并且还会阻止您创建无限任务生成器)


任务抽象

无论您采用哪种方式,您都可能希望通过创建回调来抽象任务的概念,在回调中插入每个之间的延迟,有点像''.join.

def callAndWaitBetween(tasks):
    for ..task.. in enumerate?(tasks):
        #... some solution to this problem...
        task()

作为参考,如果延迟取决于任务,那么您的任务应该返回等待多长时间。

于 2012-08-22T21:54:21.963 回答
2

试试这个:

for i in xrange(repeat):
  if i<repeat:
    time.sleep(10)
于 2012-08-22T21:53:23.193 回答
2

如果你所做的只是睡觉,你可以做到

for i in range(repeat)[:-1]:
  time.sleep(10)

但是,如果您确实需要执行某种类型的操作,那么:

sleep = [lambda: time.sleep(20) for i in range(repeat)[:-1]] + [lambda: None]

for i in xrange(repeat):
  # do stuff
  sleep.pop(0)()

如果您确实有很多迭代,请使用itertools创建生成器而不是列表sleep

于 2012-08-22T22:10:12.640 回答
0

一个while循环可能会起作用

while repeat > 0:
    #do stuff
    if repeat > 1:
        time.sleep(10)
    repeat -= 1

只需将 repeat 直接设置为循环重复的次数,而不是使用 xrange。

于 2012-08-22T22:04:11.937 回答