Gibt es ein Python-Idiom zum Auswerten einer Liste von Funktionen / Ausdrücken mit Kurzschlüssen?

8

Ich habe ein einfaches Skript geschrieben, um ein "Logikrätsel" zu lösen, die Art von Puzzle aus der Schule, wo man eine Reihe von Regeln bekommt und dann in der Lage sein muss, die Lösung für Probleme wie "Es gibt fünf Musiker namens A, B, C, D und E, die in einem Konzert spielen, spielen jeweils nacheinander ... wenn A vor B geht und D nicht zuletzt ... wie ist die Reihenfolge, wer wann spielt? " usw.

Um mögliche Lösungen zu bewerten, schrieb ich jede "Regel" als eine separate Funktion, die auswerten würde, ob eine mögliche Lösung (die einfach als eine Liste von Strings dargestellt wird) gültig ist, zum Beispiel

%Vor%

Ich bin daran interessiert, den pythonischen Weg zu finden, um zu testen, ob eine mögliche Lösung alle diese Regeln übersteht, mit der Möglichkeit, die Auswertung von Regeln zu stoppen, nachdem die erste fehlgeschlagen ist.

Zuerst schrieb ich die einfachste mögliche Sache:

%Vor%

Aber das schien ziemlich hässlich. Ich dachte, ich könnte das vielleicht etwas eleganter lesen mit etwas wie einem Listenverständnis ...

%Vor%

... aber dann habe ich gemerkt, dass das Listenverstehen erzeugt wird, bevor die all() -Funktion ausgewertet wird, dass dies den Nebeneffekt hat, überhaupt nicht kurzgeschlossen zu sein - jede Regel wird ausgewertet, selbst wenn die erste gibt False zurück.

Meine Frage ist also: Gibt es einen pythonisch / funktionalen Weg, um eine Liste von True / False -Ausdrücken mit Kurzschlüssen auszuwerten, ohne eine lange Liste von% co_de ausschreiben zu müssen %?

    
matt b 04.08.2010, 13:08
quelle

1 Antwort

13

Verwenden Sie einen Generatorausdruck :

%Vor%

Syntaktischer Zucker: Sie können die zusätzlichen Klammern weglassen:

%Vor%

Ein Generator ist (im Prinzip) ein Objekt mit einer .next() -Methode, die das nächste Element in einer iterierbaren Methode zurückgibt. Dies bedeutet, dass sie nützliche Dinge tun können, wie zum Beispiel das Lesen einer Datei in Blöcken, ohne sie in den Speicher zu laden, oder das Iterieren zu riesigen Ganzzahlen. Sie können sie transparent mit for loops durchlaufen; Python behandelt es hinter den Kulissen. Zum Beispiel ist range ein Generator in Py3k.

Sie können Ihre eigenen benutzerdefinierten Generatorausdrücke rollen, indem Sie die yield -Anweisung anstelle von return in einer Funktionsdefinition verwenden:

%Vor%

und Python wird den Status der Funktion speichern und so weiter. Sie sind fantastisch!

    
katrielalex 04.08.2010, 13:11
quelle