2015-10-15 6 views
6

ich Python zu verwenden, das Gefühl über einige Code wie diesen sehr verwirrt [nicht von mir geschrieben]:wie jede

version = any(func1(), func2()) # wrong, should be any([func1(), func2()]) 

def func1(): 
    if something: 
     return 1 
    else: 
     return None 

def func2(): 
    if something: 
     return 2 
    else: 
     return 3 

version eine num sein muss. wenn [func1(), func2()][1, None] ist, sollte 1 zurückgeben, wenn [None, 2], sollte 2 zurückkehren, wenn [1, 2], zurückgeben sollte 1.

so denke ich, es ist falsch any() in diesem Code zu verwenden, da any() nur True oder False zurückzukehren. Wenn ich diese Logik auf einen anderen Weg umschreibe, kann ich keinen graziösen Weg als Pythoner finden.

Ich möchte wissen, ob any() die Logik erreichen kann, wenn nicht, wie es anmutig zu erreichen?

+1

Fragen Sie, welches Szenario 'any()' verwendet, oder wie Sie diesen Code vereinfachen können? – Nayuki

+0

@NayukiMinase Ich möchte wissen, ob 'any()' die Logik erreichen kann, wenn nicht, wie man es anmutig erreicht? –

Antwort

12

Sie können einfach or hier verwenden.

version = func1() or func2() 

Stellen Sie sicher, dass die Funktionen definiert sind, bevor Sie versuchen, sie aufzurufen.

Dies funktioniert, weil or den ersten True-like-Wert oder den letzten Wert zurückgibt (wenn kein Wert True-like ist). Und "None" wird im Booleschen Kontext als falsch-ähnlich angesehen.

+2

Das ist ein guter Weg, danke. –

5

@ AnandSKumar's Antwort ist optimal. Aber nur Sie auf jeder einige Informationen zu geben, wenn Sie daran interessiert sind:

dieses Beispiel nehmen:

>>> def foo(): 
... return 2 
... 
>>> def boo(): 
... return 3 
... 
>>> def doo(): 
... return 4 
... 
>>> f = [foo, boo, doo] 

>>> any(i() < 3 for i in f) 
True 

Letztlich, was innerhalb des ANY geschieht, iterieren über die Anordnung von Methoden j, und geben Sie an, ob jedes Element weniger als 3 ist, was das "any" in diesem Fall tun wird, ist die Rückgabe "ANY" Bedingung, die das entspricht. Selbst wenn Sie einen Falschen finden, wird er trotzdem True zurückgeben.

Es gibt eine andere ähnliche Methode namens "all", die sicherstellen wird, dass alle Bedingungen erfüllt sind, basierend auf Ihrer Bedingung, die Sie überprüfen. Hier ist das Beispiel:

>>> all(i() < 3 for i in f) 
False 

Also, wie Sie sehen können, da eine Bedingung fehlgeschlagen ist, wird False zurückgegeben.

4

Für die beliebige Länge Fall (wo explizit or Verkettungs keinen Sinn macht), können Sie eine Version von any machen, die den ersten truthy Wert oder einen bestimmten Wert zurückgibt, wenn alle Ergebnisse sind falsy mit:

# If on Py2, you'll want to do this to get shortcircuiting behavior 
from future_builtins import filter 

result = next(filter(None, iterable_to_check), False) # False can be replaced with a chosen default 

Die filter erzeugt nur "truthy" -Werte, und die beiden arg next erhält den ersten "truthy" -Wert oder den Standardwert, wenn filter keine "truthy" -Werte findet.

Wenn die iterable_to_check ist ein nicht leere Sequence (und nicht nur Iterable), können Sie genau das Verhalten von verketteten or s mithalten können (das „falsy“ Ergebnis ist der letzte Wert, nicht ein bestimmte Wert wie False oder None) mit:

result = next(filter(None, sequence_to_check), sequence_to_check[-1]) 

das letzte Element ("truthy" oder "falsy") als das Ergebnis zu verwenden, wenn alle Elemente "falsy" waren.

Um klar zu sein, wenn die Menge der Dinge zu prüfen ist behoben und kleiner, explizite or per Anand die Antwort ist der bessere Weg zu gehen.