Skip to main content
 首页 » 编程设计

python之While 循环何时中断

2025年05月04日14yjmyzz

我有一个 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 循环的目的......

请您参考如下方法:

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

如果 self.count 达到 0,您似乎想尽早退出 for 循环。真的没有办法那直接每次递减时都必须检查。

但是,您实际上根本不需要self.count。您在 append 到 workDays 的相同位置完全递减它。所以,只需检查您是否已经拥有其中的 5 个。换句话说,每个 self.count -= 1 变成:

if len(workDays) >= 5: break 

实际上有一种方法可以在 Python 中执行(我认为)您想要的操作:使用生成器而不是列表。如果您 yield 每个值而不是将其附加到 list 然后在最后返回该 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): 

在您了解生成器之前,生成器可以做的很多事情都感觉很神奇——这通常意味着您在了解生成器之前不应该做这些事情。所以,如果这对你来说没有意义,不要只是拿起它并使用它。但如果它提示您学习如何编写和使用生成器函数,那就太好了!