Ich habe an einem Projekt für eine Klasse gearbeitet, bei dem mein Code nicht die gleichen Ergebnisse wie der Referenzcode lieferte.
Ich habe meinen Code Zeile für Zeile mit dem Referenzcode verglichen, sie sahen fast genauso aus. Alles schien logisch gleichwertig zu sein. Schließlich fing ich an, Leitungen auszutauschen und zu testen, bis ich die Leitung gefunden hatte, die wichtig war.
Es stellte sich heraus, dass es so etwas war (BEARBEITEN: Der genaue Code ist weiter unten):
# my version:
max_q = max([x for x in self.getQValues(state)])
# reference version which worked:
max_q = max(x for x in self.getQValues(state))
Das hat mich verblüfft. Ich habe einige Experimente mit dem Python (2.7) -Interpreter ausprobiert und Tests mit max
Listenverständnissen mit und ohne eckige Klammern durchgeführt. Die Ergebnisse schienen genau gleich zu sein.
Selbst beim Debuggen über PyCharm konnte ich keinen Grund finden, warum meine Version nicht genau das gleiche Ergebnis wie die Referenzversion lieferte. Bis zu diesem Punkt dachte ich, ich hätte einen ziemlich guten Überblick darüber, wie das Listenverständnis funktioniert (und wie die max()
Funktion funktioniert), aber jetzt bin ich mir nicht so sicher, weil dies eine so seltsame Diskrepanz ist.
Was ist denn hier los? Warum liefert mein Code andere Ergebnisse als der Referenzcode (in 2.7)? Wie unterscheidet sich das Übergeben eines Verständnisses ohne Klammern vom Übergeben eines Verständnisses mit Klammern?
EDIT 2: Der genaue Code war folgender:
# works
max_q = max(self.getQValue(nextState, action) for action in legal_actions)
# doesn't work (i.e., provides different results)
max_q = max([self.getQValue(nextState, action) for action in legal_actions])
Ich denke nicht, dass dies als Duplikat markiert werden sollte - ja, die andere Frage betrifft den Unterschied zwischen Verständnisobjekten und Listenobjekten, aber nicht, warum max()
unterschiedliche Ergebnisse erzielt werden würden, wenn eine "eine von X-Verständnis erstellte Liste" anstelle von " X Verständnis 'allein.
Verlieren Sie eine lokale Variable, die sich auf den späteren Code auswirkt?
# works
action = 'something important'
max_q = max(self.getQValue(nextState, action) for action in legal_actions)
assert action == 'something important'
# doesn't work (i.e., provides different results)
max_q = max([self.getQValue(nextState, action) for action in legal_actions])
assert action == 'something important' # fails!
Generator- und Wörterbuchverständnisse erstellen einen neuen Bereich, vor py3 jedoch keine Listenverständnisse, um die Abwärtskompatibilität zu gewährleisten
Einfache Möglichkeit zum Testen - ändern Sie Ihren Code in:
max_q = max([self.getQValue(nextState, action) for action in legal_actions])
max_q = max(self.getQValue(nextState, action) for action in legal_actions)
Angenommen, es self.getQValue
ist rein, dann besteht der einzige dauerhafte Nebeneffekt der ersten Zeile darin, sich mit lokalen Variablen herumzuschlagen. Wenn dies nicht funktioniert, ist dies die Ursache für Ihr Problem.
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen