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が変更される唯一の関数です。それでも、プログラムがself.countに対して-1を出力しているため、ループが少なくとも1カウント長すぎるように見えるという奇妙な結果が得られています。これが起こっているべきですか?whileループは、2番目のself.countがゼロに達するのを終了するべきではありませんか、それとも最初にforループを終了する必要がありますか?self.countがゼロであるかどうかをチェックし、ゼロである場合は中断するself.countが減少した後、条件付きロジックを追加する必要がありますか?それはwhileループの目的のようです...

4

4 に答える 4

4

whileループは、その条件が真でなくなるとすぐにループの途中で自動的に終了することはありません。各ループの開始時に条件をチェックするだけです。早く出たい場合は、明示的に(または、関数やループ外のハンドラーなどbreak、ローカル以外の何かを実行する)必要があります。returnraiseexcept

あなたがやろうとしていることはfor、もし0に達したとしても、早くループから抜け出すことのself.countようです。それを直接行う方法は本当にありません。デクリメントするたびにチェックする必要があります。

ただし、実際にはまったく必要ありませんself.count。とまったく同じ場所でデクリメントしappendますworkDays。ですから、まだ5つあるかどうかを確認してください。つまり、それぞれが次のようにself.count -= 1なります。

if len(workDays) >= 5: break

Pythonで(私が思うに)やりたいことを実際に行う方法があります。リストの代わりにジェネレーターを使用します。それぞれの値をyieldaに追加して最後に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):

ジェネレーターが実行できることの多くは、理解するまでは魔法のように感じます。つまり、ジェネレーターについて学習するまでは、ジェネレーターを実行しないでください。したがって、これが意味をなさない場合は、それを手に取って使用しないでください。しかし、ジェネレーター関数の作成方法と使用方法を学ぶように促された場合は、すばらしいです。

于 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ループは、ループごとに1回条件をチェックします。常に状態をチェックするわけではありません。これは、コードブロック中に何らかの制御フローステートメント(、、、、など)が実行されない限り、コードブロック全体が各条件チェックの間に実行されることを意味しcontinueます。breakreturn

実際には、ループごとに1回のこの条件チェックには、パフォーマンス上の利点があり(コンピューターは常に条件を評価する必要はありません) 、プログラムの循環的複雑度を制限します。

于 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 に答える