1

我有一个while循环:

def setWorkDays(dayNameList):
            workDays = []
            while self.count > 0: #continue loop until all 5 work days have been filled or the loop breaks at the end 
                for day in dayNameList: #iterate over days, adding days to work days if they are not free days, AL days, preferred days, or free Saturdays 
                    if day in self.freeDays or day in self.alDays or (day == 'Saturday' and self.satOff is True):
                        continue
                    elif day in self.programDays:
                        workDays.append(day)
                        self.count -= 1
                    elif self.preferredDay is not None and day in self.preferredDay:
                        continue
                    else:
                        workDays.append(day)
                        self.count -= 1
                if self.preferredDay not in self.workDays: #if iteration completes, 5 work days have not been filled, and the preferred day has not been added, add the preferred day 
                    workDays.append(self.preferredDay)
                    self.count -=1
                return workDays

循环背后的想法是 self.count 达到 0 的第二个,循环终止。这是修改 self.count 的唯一函数。然而我得到了奇怪的结果,循环似乎持续了至少 1 个计数太长,因为程序在某些情况下为 self.count 输出 -1。这应该发生吗?while 循环不应该终止第二个 self.count 达到零,还是必须先完成 for 循环?我是否应该在 self.count 递减后添加条件逻辑来检查 self.count 是否为零,如果为零则中断?这似乎是while循环的目的......

4

4 回答 4

4

while一旦条件不再为真,循环不会在循环中自动退出;它只是在每个循环开始时检查条件。如果你想早点离开,你需要break明确地(或者做一些非本地的事情,比如return从函数或循环外的处理程序)raiseexcept

看起来你想要做的是for尽早退出循环,如果self.count曾经达到 0。真的没有办法直接做到这一点。每次减量时都必须检查。

但是,你真的根本不需要self.count。您在相同的地方减少appendworkDays。因此,只需检查您是否拥有其中的 5 个。换句话说,每个都self.count -= 1变成:

if len(workDays) >= 5: break

实际上有一种方法可以在 Python 中做(我认为)你想要的:使用生成器而不是列表。如果你yield每个值而不是将它附加到 alist然后list在最后返回它,那么一旦你得到 5 个条目,你就停止迭代生成器。

例如:

def setWorkDays(dayNameList):
    while self.count > 0: #continue loop until all 5 work days have been filled or the loop breaks at the end 
        for day in dayNameList: #iterate over days, adding days to work days if they are not free days, AL days, preferred days, or free Saturdays 
            if day in self.freeDays or day in self.alDays or (day == 'Saturday' and self.satOff is True):
                continue
            elif day in self.programDays:
                yield day
            elif self.preferredDay is not None and day in self.preferredDay:
                continue
            else:
                yield day
        if self.preferredDay not in self.workDays: #if iteration completes, 5 work days have not been filled, and the preferred day has not been added, add the preferred day 
            yield day

workDays = [setWorkDays(dayNameList) for _ in range(5)]

通常,您甚至不需要list,您需要做的就是迭代它。为此,您可以这样做:

for workDay in (setWorkDays(dayNameList) for _ in range(5)):

或者:

for workDay in itertools.islice(setWorkDays(dayNameList), 5):

生成器可以做的很多事情在你理解它们之前感觉就像魔术一样——这通常意味着在你了解生成器之前你不应该做它们。因此,如果这对您没有意义,请不要随便拿起并使用它。但是,如果它提示您学习如何编写和使用生成器函数,那就太好了!

于 2013-01-09T21:58:02.140 回答
1

self.count您在while循环中多次递减。

循环只会在块的开头中断。所以可能发生的是self.count在块的开头是正值,然后在单个块中递减到负值。

于 2013-01-09T21:55:50.577 回答
1

任何语言(我知道)的while循环都不会按您期望的方式工作。

通常,while循环具有以下格式:

while <condition>:
  <code block>

while 循环在每个循环中检查一次条件。它不会不断检查情况。这意味着整个代码块将在每个条件检查之间执行,除非在代码块期间执行某些控制流语句(例如continuebreakreturn)。

在实践中,每个循环一次的条件检查具有性能优势(计算机不必不断地评估条件)以及限制程序的圈复杂度

于 2013-01-09T21:59:42.703 回答
1

这似乎可以满足您的需要:

def setWorkDays(dayNameList):
     workDays = []
     for day in dayNameList:
         if day in self.freeDays or day in self.alDays or (
             day == 'Saturday' and self.satOff):
                 continue
         elif day in self.programDays:
             workDays.append(day)
             self.count -= 1
         elif self.preferredDay is not None and day in self.preferredDay:
             continue
         else:
             workDays.append(day)
             self.count -= 1
         if self.count <= 0:
              break
     else:
         if self.preferredDay not in self.workDays:
             workDays.append(self.preferredDay)
             self.count -=1
     return workDays
于 2013-01-09T21:59:49.087 回答