Python: if-else verstehen und anwenden

Die if-else-Anweisung in Python (zu Deutsch: „wenn-(dann)-ansonsten“) ist eine konditionelle Verzweigung und damit eine grundlegende Kontrollstruktur. Die Nutzung einer Verzweigung erlaubt, abweichende Code-Pfade je nach einer zur Laufzeit anzutreffender Bedingung zu beschreiten. Wir erklären, wie if-else in Python funktioniert und eingesetzt wird.

SSL-Zertifikate von IONOS!

Wahren Sie dank SSL-Zertifikaten die Geheimhaltung Ihres Online-Verkehrs und stärken Sie das Vertrauen Ihrer Kunden in die Sicherheit Ihrer Webseite.

Geprüfte Sicherheit
Bis zu 256-bit Verschlüsselung
Einfache Aktivierung

Was ist eine if-else-Anweisung?

Bei der if-else-Anweisung handelt es sich um eine konditionelle Verzweigung. Vorstellen kann man sich das wie eine Weiche: In Abhängigkeit von einem Schaltelement wird von zwei möglichen Wegen ausschließlich einer beschritten. Python ist eine interpretierte Sprache; der Interpreter liest Zeilen des Quellcodes von oben nach unten ab. Im einfachsten Fall ergibt sich ein strikt linearer Programmfluss: Alle Zeilen werden nacheinander gelesen, interpretiert und ausgeführt.

Diesem simplen Schema folgend sind jedoch keine komplexen Programme möglich. Erst durch den Einsatz von Kontrollstrukturen ergibt sich die im praktischen Einsatz benötigte Variabilität des ausgeführten Codes. Eine Verzweigung erlaubt die konditionelle Ausführung bestimmter Code-Teile. Als weitere Kontrollstrukturen kommen insbesondere Python-for-Schleifen und Pyhton-while-Schleifen zum Einsatz, die die wiederholte Ausführung von Code-Teilen ermöglichen.

Tipp

Lernen Sie, Python-Code zu schreiben – mit unserem Python-Tutorial!

Wie funktioniert if-else in Python?

Generell verhält sich die if-else-Anweisung in Python ähnlich wie aus anderen Sprachen bekannt. Es gibt jedoch einige Python-spezifische Besonderheiten. Schauen wir uns im Detail an, wie die if-else-Anweisung in Python funktioniert und wie sie sich im Gegensatz zu anderen Sprachen verhält.

Generelle Syntax der if-else-Anweisung in Python

Die generelle Syntax der if-else-Anweisung in Python lässt sich direkt in Python-Code ausdrücken. Wir definieren eine Kondition und legen im Körper der if-Anweisung beispielshalber einen Funktionsaufruf als Code-Pfad fest, der beschritten wird, wenn die Kondition wahr wird. Ferner legen wir im else-Körper einen Code-Pfad fest, der andernfalls beschritten wird:

if condition:
    if_body()
else:
    else_body()

Die definierte Kondition kann entweder wahr sein (True) oder nicht wahr (False). Wir verdeutlichen das Muster, indem wir das Literal True oder False direkt als Kondition eintragen. Es ergibt sich ein statischer Programmfluss, bei dem garantiert jeweils nur einer der beiden Pfade beschritten wird:

if False:
    # dieser Code wird nie ausgeführt
    if_body()
else:
    else_body()
if True:
    if_body()
else:
    # dieser Code wird nie ausgeführt
    else_body()

Selbstverständlich ist dieses Muster nicht praktisch, sondern dient nur zum Veranschaulichen. Anstelle eines statischen True/False-Wertes kommt als Kondition ein Ausdruck zum Einsatz. Der Ausdruck wird zur Laufzeit des Programms ausgewertet. Man spricht davon, dass der Ausdruck „evaluiert“ wird. Beim Evaluieren des Ausdrucks ergibt sich ein Wahrheitswert. Je nachdem, ob als Wahrheitswert True oder False herauskommt, verzweigt das Programm in die eine oder die andere Richtung.

Wichtig zu verstehen ist, dass der else-Teil optional ist. Der im else-Körper befindliche Code wird nur ausgeführt, wenn die Kondition nicht zutrifft. Dies ist jedoch nicht zwingend notwendig. Oft genügt eine alleinstehende if-Anweisung:

if condition:
    if_body()

Ein kleiner Hinweis zur Nomenklatur: Wir haben die Begriffe „Anweisung“ und „Ausdruck“ benutzt, ohne diese zu erklären. Dabei ist es durchaus wichtig, zu verstehen, was damit gemeint ist. Denn diese beiden grundlegende Begriffe ziehen sich durch sämtliche Programmiersprachen. Hier die Bedeutung der Begriffe im Überblick:

Begriff Englische Entsprechung Erläuterung
Anweisung Statement Aktion, die ausgeführt wird; beeinflusst in der Regel den Programmverlauf
Ausdruck Expression Term, der beim Evaluieren einen Wert zurückgibt

Mit der elif-Anweisung in Python mehrere exklusive Konditionen abfragen

Neben der bekannten if-else-Anweisung existiert in Python die verwandte elif-Anweisung. Auf eine if-Anweisung folgen optional mehrere elif-Anweisungen, gefolgt von einem optionalen else-Block. Eine elif-Anweisung wird nur dann ausgeführt, wenn keine der vorgeschalteten Konditionen wahr geworden ist. So wird garantiert, dass ausschließlich ein einzelner definierter Code-Pfad beschritten wird:

if condition:
    if_body()
elif other_condition:
    elif_body()
elif another_condition:
    another_elif_body()
else:
    else_body()

Hier die Regeln für den Aufbau einer verketteten if-elif-else-Verzweigung:

Verzweigungs-Anweisung Anzahl in Kombination
if genau eine
elif null oder mehrere
else null oder eine

Wie wird if-else in Python genutzt?

Die if-else-Anweisung ist in Python wie in anderen Sprachen eine grundlegende Funktionalität. Naturgemäß gibt es viele verschiedene Einsatzmöglichkeiten. Wir zeigen häufig anzutreffende Beispiele inklusive Best Practices und Anti-Patterns.

Korrekte Nutzung der if-Kondition in Python

Schauen wir uns zunächst an, wie die Kondition einer Verzweigungs-Anweisung funktioniert. Die Kondition wird als boolescher Ausdruck interpretiert, der zu einem der Wahrheitswerte True oder False evaluiert. Es ist daher unnötig, explizit auf Gleichheit mit einem booleschen Literal zu testen:

if expression == True:
    ...

Auch wenn es sich beim expliziten Abgleich mit True nicht um einen echten Fehler handelt, wirkt der Code unprofessionell. Erfahrene Programmierer schreiben stattdessen:

if expression:
    ...

Schauen wir uns das Anti-Pattern an einem Beispiel an. Nehmen wir an, dass eine Funktion is_odd() für eine Zahl True zurückgibt, wenn die Zahl ungerade ist. Andernfalls gibt die is_odd-Funktion False zurück. Wir nutzen die Funktion innerhalb einer if-Anweisung und geben einen entsprechenden Text aus:

if is_odd(number) == True:
    print("The number is odd.")

Stellen wir uns vor, was beim Durchlaufen der Verzweigung mit einer ungeraden Zahl passiert. Zunächst evaluiert der Ausdruck 'is_odd(number) == True' zu 'True == True'. Letzterer evaluiert wiederum zu 'True'; der if-Körper wird ausgeführt. Sinnvoller ist, den von der is_odd-Funktion zurückgegebenen booleschen Wert direkt als Kondition zu nutzen:

if is_odd(number):
    print("The number is odd.")

Optionalen Code mit if-Anweisung in Python ausführen

Stellen wir uns die folgende Situation vor: Wir haben einen Code-Block mit bestimmter Funktion. Die Zeilen werden nacheinander ausgeführt. Jedoch soll ein Bestandteil des Codes nicht immer ausgeführt werden, sondern nur dann, wenn eine Bedingung zutrifft. Um dieses Muster umzusetzen, benötigen wir lediglich eine if-Anweisung. Hier dargestellt am Beispiel einer Nutzerregistrierungs-Routine:

def register_user(user_data, do_newsletter_signup = False):
    # create user account
    user_account = create_account(user_data)
    # sign up for newsletter — only if requested by user
    if do_newsletter_signup:
        signup_newsletter(user_account)
    # send confirmation mail
    send_confirmation_mail(user_account)

Zwei distinkte Fälle mit if-else-Anweisung in Python unterscheiden

Häufig müssen Programme zwischen zwei sich gegenseitig ausschließenden Fällen unterscheiden. Wenn sich logisch erschließt, dass es keine weiteren Fälle geben kann, ist es sinnvoll, eine if-else-Anweisung einzusetzen. Wir testen exemplarisch, ob eine Person ein bestimmtes Alter erreicht hat, und geben jeweils ein passendes Ergebnis aus:

def is_of_age(person, age_limit = 18):
    if person.age >= age_limit:
        print("You're old enough")
    else:
        print("Sorry, wait some more")

Mehrere exklusive Fälle mit elif-Anweisungen in Python unterscheiden

Gibt es mehr als zwei sich gegenseitig ausschließende Fälle, zwischen denen wir unterscheiden möchten, kommen verkettete elif-Anweisungen zum Einsatz. Ein abschließendes else dient dazu, unbekannte Variation zu fangen. Wir ordnen Ländernamen den korrespondierenden Länder-Codes zu:

def get_country_from_code(country_code):
    if country_code == 'DE':
        country = "Deutschland"
    elif country_code == 'ES':
        country = "España"
    elif country_code == 'FR':
        country = "France"
    elif country_code == 'GB':
        country = "Great Britain"
    elif country_code == 'IT':
        country = "Italia"
    else:
        country = None
    return country

Sofern sich die elif-Kette innerhalb einer Funktion befindet, ist es manchmal besser, mehrere unabhängige if-Anweisungen zu nutzen. So sparen wir uns die Zuweisung im elif-Körper. Mittels der return-Anweisung verlassen wir die Funktion, wenn eine der Bedingungen wahr wird. Statt dem abschließenden else kommt eine zuletzt stehende return-Anweisung zum Einsatz, die nur erreicht wird, wenn keine der Konditionen True war:

def get_country_from_code(country_code):
    if country_code == 'DE':
        return "Deutschland"
    if country_code == 'ES':
        return "España"
    if country_code == 'FR':
        return "France"
    if country_code == 'GB':
        return "Great Britain"
    if country_code == 'IT':
        return "Italia"
    return None

Verkettete elif-Anweisungen sind ein bekanntes Muster älterer Sprachen. In Python ist es oft direkter, ein „Dictionary Lookup“ zu verwenden. Wir definieren die Zuordnung der Codes zu den Ländernamen direkt und extrahieren den Namen anhand des Codes. Anstatt des abschließenden else nutzen wir die eingebaute get-Methode, die als zweiten Parameter einen Default-Wert entgegennimmt:

def get_country_from_code(country_code):
    countries = {
        'DE': "Deutschland",
        'ES': "España",
        'FR': "France",
        'GB': "Great Britain",
        'IT': "Italia",
    }
    country = countries.get(country_code, None)
    return country

Mit der if-Anweisung in Python überprüfen, ob ein Objekt Daten enthält

Python ist eine dynamisch und lose typisierte Sprache. Statt an Variablen sind Typen an Werte gebunden. Je nach Einsatz finden ggf. implizite Konversionen zwischen Typen statt. Im Kontext der booleschen Ausdrücke spricht man in Erweiterung der Wahrheitswerte True und False auch von „truthy“ und „falsy“.

Das bedeutet, dass die Kondition einer if-Anweisung in Python nicht explizit zu True oder False evaluieren muss. Vielmehr können Werte anderer Typen als Kondition zum Einsatz kommen. Diese werden bestimmten Regeln folgend als boolesche Werte interpretiert.

Zitat

„Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations […]

[...] An object is considered true unless its class defines either a __bool__() method that returns False or a __len__() method that returns zero [...]“ – Quelle: https://docs.python.org/3/library/stdtypes.html#truth-value-testing

Übersetzung: „Jedes Objekt lässt sich auf seinen Wahrheitswert testen, um diesen in einer if- oder while-Anweisung oder in einer der booleschen Operationen zu nutzen [...]

[...] Ein Objekt wird als wahr bewertet, es sei denn, es definiert entweder eine __bool__()-Methode, die False zurückgibt oder eine __len__()-Methode, die null zurückgibt [...]“ (übersetzt von IONOS)

Wir machen uns dieses Muster zunutze, um zu überprüfen, ob ein Objekt Daten enthält. Da der folgende Text leer ist, wird eine entsprechende Meldung ausgegeben:

text = ''
if not text:
    print("No text given")

Die folgenden Objekte evaluieren im booleschen Kontext zu False und werden daher als „falsy“ bezeichnet:

Objekt Erläuterung
False, None Konstanten, die der Definition nach False sind
0, 0.0, Decimal(0), Fraction(0, 1), etc. Zahl, die null repräsentiert
'', (), [], {}, set(), range(0), etc. Leere Sequenz oder Kollektion

Ein weiteres Beispiel mit einer leeren Liste:

books_in_library = []
if not books_in_library:
    print("Library is empty")

Alle anderen Objekte evaluieren zu True:

number = 42
if number:
    print("Number exist")

Binären Schalter mit if-else in Python implementieren

Auch zum Hin- und Herschalten zwischen zwei exklusiven Zuständen kommt eine if-else-Anweisung zum Einsatz. Das Prinzip ähnelt einem Lichtschalter und wird im Englischen als „Toggle“ bezeichnet. Wir definieren eine Funktion, die den Zustand eines Lichts umdreht:

def toggle_light(light):
    if light == 'on':
        return 'off'
    else:
        return 'on'

Vielleicht sehen Sie es bereits: Das geht noch einfacher. Sofern der Zustand nicht als String, sondern als boolescher Wert repräsentiert wird, bietet sich an, komplett auf die if-Anweisung zu verzichten. Stattdessen nutzen wir den logischen NICHT-Operator, um den booleschen Wert umzudrehen:

def toggle(boolean):
    return not boolean

Mit Early Return verschachtelte if-Anweisungen in Python auflösen

In der Praxis ist es üblich, bestimmten Code auszuführen, wenn mehrere Konditionen gleichzeitig wahr werden. Dies führt bei unerfahrenen Programmierern schnell zu verschachtelten if-Anweisungen. Jedoch handelt es sich dabei um schlechten Stil. Denn tief verschachtelte Verzweigungen lassen sich schwer überblicken und schlecht warten.

Betrachten wir ein Beispiel: Wir schreiben eine Funktion, die die Aussage darüber wiedergibt, ob eine Person wählen darf. Wir überprüfen zunächst, ob die Person ein Ausweisdokument hat. Im Anschluss überprüfen wir, ob die Person das Wahlalter bereits erreicht hat. Eine erste Implementation der Funktion enthält verschachtelte if-Anweisungen:

def person_may_vote(person, voting_age = 18):
    if person.has_id():
        if person.get_age() >= voting_age:
            return True

Ein unmittelbares Problem dieser Implementation ist, dass der wichtigste Code weiter eingerückt wird, je mehr Bedingungen getestet werden. Zum Auflösen verschachtelter if-Anweisungen kommt die Best Practice des „Early Return“ zum Einsatz. Dabei überprüfen wir am Anfang der Funktion, ob die einzelnen Bedingungen erfüllt sind. Ist eine Bedingung nicht erfüllt, brechen wir ab und verlassen die Funktion unter Nutzung der return-Anweisung.

Wir formulieren unsere Funktion neu, um Early Returns zu nutzen. Häufig erfordert dies, die vorher definierten Bedingungen umzukehren. Hilfreich ist dabei ein Verständnis der booleschen Operatoren in Python. Trifft keine der negativen Bedingungen zu, wird der eigentlich interessante Code ausgeführt:

def person_may_vote(person, voting_age = 18):
    if not person.has_id():
        return False
    if person.age < voting_age:
        return False
    # if we made it here, the person may vote
    return True

Mit logischen Operatoren if-Anweisungen in Python vereinfachen und ersetzen

Wie wir bereits gesehen haben, ist es häufig notwendig, das Eintreten mehrerer Konditionen zu testen. Meist ist es suboptimal, zum Testen mehrerer Bedingungen verschachtelte if-Anweisung zu nutzen. Betrachten wir exemplarisch Code, der bestimmt, ob eine Person wählen darf:

if has_id(person):
    if is_adult(person):
        print("You may vote")

Schöner lässt sich die verkettete Bedingung unter Nutzung logischer Operatoren darstellen. Da wir testen wollen, ob beide Konditionen gleichzeitig zutreffen, nutzen wir den logischen UND-Operator. So benötigen wir nur eine einzige if-Anweisung:

if has_id(person) and is_adult(person):
    print("You may vote")

Hier ein Überblick der grundlegenden logischen Operatoren in Python:

Logischer Operator Bedeutung Python-Syntax Andere Sprachen    
UND Ausdruck ist wahr, wenn alle Operanden wahr sind; gibt den zuletzt evaluierten Operanden zurück. and &&    
ODER Ausdruck ist wahr, wenn mindestens einer der Operanden wahr ist; gibt den zuletzt evaluierten Operanden zurück. or      
NICHT Dreht Wert des Ausdrucks um. not !    

Neben dem Verknüpfen von Operanden in Konditionen werden die logischen Operatoren eingesetzt, um bestimmte if-Anweisungen zu ersetzen. Es handelt sich dabei um das Setzen von Default-Werten.

Betrachten wir ein Beispiel: Stellen wir uns vor, ein Nutzer könne für eine finanzielle Berechnung eine Währung festlegen. Aus Gründen der Benutzerfreundlichkeit soll die Wahl optional sein. Wählt der Benutzer keine Währung aus, soll EUR als Default-Wert verwendet werden. Der folgende Code bildet dieses Prinzip ab:

# user made no currency choice
currency = None
...
# further down in the program flow
if not currency:
    # set default if value missing
    currency = 'EUR'

Unter Einsatz des logischen ODER-Operators lässt sich die if-Anweisung auflösen. Wir schreiben den Code um; wird dieser ausgeführt, enthält die currency-Variable den Wert 'EUR':

# user made no currency choice
currency = None
...
# further down in the program flow
# set default if value missing
currency = currency or 'EUR'

Was genau geschieht hier? In der letzten Zeile wird der Variable 'currency' ein neuer Wert zugewiesen. Dazu wird zunächst der Ausdruck 'currency or 'EUR'' auf der rechten Seite des Gleichheitszeichens evaluiert. Der logische ODER-Operator evaluiert zunächst den linken Ausdruck, in diesem Falle 'currency'. Da dieser im Beispiel 'None' enthält und damit „falsy“ ist, wird der rechte Ausdruck 'EUR' evaluiert und als Rückgabewert für die Zuweisung verwendet.

Der konditionale if-else-Operator in Python

Neben der konditionellen Verzweigung gibt es einen weiteren Nutzen der if-else-Schlüsselworte in Python. Es handelt sich um den konditionalen Operator, auch bekannt als „ternärer“ Operator. Der konditionale Operator wird gerne eingesetzt, um in Zuweisungen zwischen zwei möglichen Werten zu unterscheiden.

Betrachten wir zunächst ein Beispiel unter Nutzung der if-else-Anweisung in Python. Der folgende Code legt Celsius oder Fahrenheit als Einheit für eine Temperaturmessung in Abhängigkeit vom gewählten Messsystem fest:

if system == 'metric':
    unit = 'C'
else:
    unit = 'F'

Unter Nutzung des konditionalen Operators lässt sich der Code zu einer einzelnen Zuweisung vereinfachen:

unit = 'C' if system == 'metric' else 'F'

Wie der Name ausdrückt, nimmt der ternäre Operator drei Operanden entgegen: die beiden möglichen Werte und einen Ausdruck als Bedingung.

Operator-Arität Erklärung Beispiel
Unär Operator nimmt einen Operanden entgegen. not boolean_operand
Binär Operator nimmt zwei Operanden entgegen. left_operand + right_operand
Ternär Operator nimmt drei Operanden entgegen. some_value if condition else other_value

Mit der match-case-Anweisung if-else in Python ersetzen

Mit dem Erscheinen der Python-Version 3.10 wurde die match-case-Anweisung eingeführt. Diese erinnert zunächst an die switch-case-Anweisung anderer Sprachen. Dort kommt switch-case zum Einsatz, um große if-elif-else-Konstrukte aufzubrechen.

Da als fehleranfällig berüchtigt, gab es switch-case in Python nie. Vielmehr handelt es sich bei der match-case-Anweisung in Python um eine an funktionale Sprachen wie Haskell angelehnte Funktionalität für „Structural Pattern Matching“. Der Nutzen geht weit über den von switch-case hinaus.

Veranschaulichen wir uns das Prinzip von match-case an einem Beispiel: Stellen wir uns vor, wir wollen Daten von Personen in verschiedenen Formaten verarbeiten. Eine Person kann entweder als einzelner Name abgebildet sein oder als Dictionary mit Name und ggf. Alter oder als Tupel von Vor- und Nachname. Ferner wollen wir den exakten Namen „Jack“ besonders behandeln:

# the name 'Jack'
person1 = 'Jack'
# just a name
person2 = 'John'
# name and age in a dict
person3 = {'name': 'Jim', 'age': 42}
# name in a dict, but no age
person4 = {'name': 'Walter', 'email': 'walter.white@example.com'}
# tuple of first and last name
person5 = ('Walther', 'White')

Schauen wir uns zunächst eine Funktion an, die eine Person in einem der Formate begrüßt. Wir nutzen eine if-elif-else-Kette und die isinstance-Funktion, um die verschiedenen Formate zu unterscheiden. Ferner kommen mit dem UND-Operator verkettete Konditionen und eine verschachtelte if-else-Anweisung zum Einsatz. Der finale Code wirkt nicht besonders übersichtlich:

def greet_person(person):
    if isinstance(person, str):
        if person == 'Jack':
            print('Jack himself has arrived')
        else:
            print(f"Hi there, {person}")
    elif isinstance(person, dict) and 'name' in person and 'age' in person:
        print(f"It's, {person['name']}. Born {person['age']} years ago")
    elif isinstance(person, dict) and 'name' in person:
        print(f"It's {person['name']}")
    elif isinstance(person, tuple) and len(person) == 2:
        first, last = person
        print(f"Hello, {first} {last}")
    else:
        print('Not sure what kind of person this is')

Schöner lässt sich der Code mit der match-case-Anweisung aufbauen. Wir beschreiben die Struktur der einzelnen Formate direkt; einzelne Werte lassen sich als Variablen extrahieren. Der Code ist übersichtlicher, weniger komplex und besser lesbar:

def match_person(person):
    match person:
        case 'Jack':
            print('Jack himself has arrived')
        case str() as name:
            print(f"Hi there, {name}")
        case {'name': name, 'age': age}:
            print(f"It's, {name}. Born {age} years ago")
        case {'name': name}:
            print(f"It's {name}")
        case (first, last):
            print(f"Hello, {first} {last}")
        case _:
            print('Not sure what kind of person this is')