1717 Stimmen

Ersetzungen für switch-Anweisung in Python?

Ich möchte eine Funktion in Python schreiben, die je nach dem Wert eines Eingabeindexes verschiedene feste Werte zurückgibt.

In anderen Sprachen würde ich ein switch o case Anweisung, aber Python scheint nicht über eine switch Aussage. Was sind die empfohlenen Python-Lösungen in diesem Szenario?

77 Stimmen

PEP zum Thema, verfasst von Guido selbst: PEP 3103

28 Stimmen

@chb In diesem PEP erwähnt Guido nicht, dass if/elif-Ketten auch eine klassische Fehlerquelle sind. Es ist ein sehr anfälliges Konstrukt.

15 Stimmen

Was bei allen Lösungen fehlt, ist die Erkennung von doppelte Fallwerte . Als Fail-Fast-Prinzip kann dies ein größerer Verlust sein als die Leistung oder die Fallthrough-Funktion.

18voto

Jeremy Cantrell Punkte 24497

Erweiterung der Idee "Diktat als Schalter". Wenn Sie einen Standardwert für Ihren Schalter verwenden möchten:

def f(x):
    try:
        return {
            'a': 1,
            'b': 2,
        }[x]
    except KeyError:
        return 'default'

19 Stimmen

Ich denke, es ist klarer, .get() für das Diktat mit dem angegebenen Standard zu verwenden. Ich ziehe es vor, Ausnahmen für außergewöhnliche Umstände zu verwenden, und es spart drei Codezeilen und eine Einrückungsebene, ohne undeutlich zu sein.

10 Stimmen

Este es ein außergewöhnlicher Umstand. Es kann sich um einen selten Umstand je nach Nutzen, aber es ist definitiv eine Ausnahme (Rückgriff auf 'default' ) aus der Regel (etwas aus diesem Diktat erhalten). Python-Programme sind so konzipiert, dass sie Ausnahmen auf Knopfdruck verwenden. Das heißt, die Verwendung von get könnte den Code möglicherweise ein bisschen schöner machen.

18voto

leo Punkte 350

Ich habe festgestellt, dass dies eine übliche Schalterstruktur ist:

switch ...parameter...
case p1: v1; break;
case p2: v2; break;
default: v3;

kann in Python wie folgt ausgedrückt werden:

(lambda x: v1 if p1(x) else v2 if p2(x) else v3)

oder klarer formatiert werden:

(lambda x:
     v1 if p1(x) else
     v2 if p2(x) else
     v3)

Die Python-Version ist keine Anweisung, sondern ein Ausdruck, der zu einem Wert ausgewertet wird.

0 Stimmen

Wie wäre es statt ...parameter... und p1(x) auch mit parameter y p1==parameter

0 Stimmen

@BobStein-VisiBone Hallo, hier ist ein Beispiel, das in meiner Python-Sitzung läuft: f = lambda x: 'a' if x==0 else 'b' if x==1 else 'c' . Als ich später anrief f(2) habe ich 'c' ; f(1) , 'b' und f(0) , 'a' . Was p1(x) betrifft, so bezeichnet es ein Prädikat, das, solange es True o False egal, ob es sich um einen Funktionsaufruf oder einen Ausdruck handelt, es ist in Ordnung.

0 Stimmen

@BobStein-VisiBone Ja, Sie haben Recht! Danke :) Damit der mehrzeilige Ausdruck funktioniert, sollten Klammern gesetzt werden, entweder wie in Ihrem Vorschlag, oder wie in meinem geänderten Beispiel.

16voto

thomasf1 Punkte 1732

Die von mir verwendeten Lösungen:

Eine Kombination aus 2 der hier geposteten Lösungen, die relativ einfach zu lesen ist und Standardeinstellungen unterstützt.

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}.get(whatToUse, lambda x: x - 22)(value)

wobei

.get('c', lambda x: x - 22)(23)

schaut auf "lambda x: x - 2" im Diktat und verwendet es mit x=23

.get('xxx', lambda x: x - 22)(44)

findet es nicht im Diktat und verwendet den Standard "lambda x: x - 22" con x=44 .

15voto

Felix Martinez Punkte 472

Sie können ein versendetes Diktat verwenden:

#!/usr/bin/env python

def case1():
    print("This is case 1")

def case2():
    print("This is case 2")

def case3():
    print("This is case 3")

token_dict = {
    "case1" : case1,
    "case2" : case2,
    "case3" : case3,
}

def main():
    cases = ("case1", "case3", "case2", "case1")
    for case in cases:
        token_dict[case]()

if __name__ == '__main__':
    main()

Ausgabe:

This is case 1
This is case 3
This is case 2
This is case 1

0 Stimmen

Ich benutze das manchmal, aber es ist nicht so klar wie if/elif/elif/else

14voto

JD Graham Punkte 169

Ich habe die einfache Antwort, nach der ich gesucht habe, bei der Google-Suche nicht gefunden. Aber ich habe es trotzdem herausgefunden. Es ist wirklich ganz einfach. Ich beschloss, es zu posten und vielleicht ein paar weniger Kratzer am Kopf eines anderen zu verhindern. Der Schlüssel ist einfach "in" und Tupel. Hier ist das Verhalten der Switch-Anweisung mit Fall-Through, einschließlich RANDOM Fall-Through.

l = ['Dog', 'Cat', 'Bird', 'Bigfoot',
     'Dragonfly', 'Snake', 'Bat', 'Loch Ness Monster']

for x in l:
    if x in ('Dog', 'Cat'):
        x += " has four legs"
    elif x in ('Bat', 'Bird', 'Dragonfly'):
        x += " has wings."
    elif x in ('Snake',):
        x += " has a forked tongue."
    else:
        x += " is a big mystery by default."
    print(x)

print()

for x in range(10):
    if x in (0, 1):
        x = "Values 0 and 1 caught here."
    elif x in (2,):
        x = "Value 2 caught here."
    elif x in (3, 7, 8):
        x = "Values 3, 7, 8 caught here."
    elif x in (4, 6):
        x = "Values 4 and 6 caught here"
    else:
        x = "Values 5 and 9 caught in default."
    print(x)

Bietet:

Dog has four legs
Cat has four legs
Bird has wings.
Bigfoot is a big mystery by default.
Dragonfly has wings.
Snake has a forked tongue.
Bat has wings.
Loch Ness Monster is a big mystery by default.

Values 0 and 1 caught here.
Values 0 and 1 caught here.
Value 2 caught here.
Values 3, 7, 8 caught here.
Values 4 and 6 caught here
Values 5 and 9 caught in default.
Values 4 and 6 caught here
Values 3, 7, 8 caught here.
Values 3, 7, 8 caught here.
Values 5 and 9 caught in default.

0 Stimmen

Wo genau liegt hier der Fallstrick?

0 Stimmen

Huch! Es gibt dort einen Durchfall, aber ich trage nicht mehr zu Stack Overflow bei. Ich mag SIE überhaupt nicht. Ich mag die Beiträge von anderen, aber eben nicht Stackoverflow. Wenn Sie fall through für FUNKTIONALITÄT verwenden, dann wollen Sie bestimmte Bedingungen in einer case-Anweisung in einem switch (einem catch all) abfangen, bis Sie eine break-Anweisung in einem switch erreichen.

2 Stimmen

Hier werden sowohl die Werte "Hund" als auch "Katze" durchfallen und von derselben Funktionalität behandelt, d. h. sie werden als "vierbeinig" definiert. Es handelt sich um ein ABSTRACT-Äquivalent zu fall through und verschiedenen Werten, die von der SAME case-Anweisung behandelt werden, wenn ein Bruch auftritt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X