Editor-Trick des Tages: Zeilen verschieben, Zeilen verdoppeln

In VSCode können Sie mit der Tastenkombination Alt + ArrowUp/ArrowDown die Zeile, in der der Cursor sich befindet, nach oben bzw. unten verschieben! Probieren Sie es aus: Kopieren Sie die folgenden Zeilen in Ihren Editor und sortieren Sie sie aufsteigend, indem Sie nur Alt und die Pfeiltasten verwenden.

1
5
2
8
4

Wenn Sie stattdessen Alt + Shift + ArrowUp/ArrowDown drücken, wird die Zeile, in der der Cursor sich befindet, verdoppelt. Probieren Sie es aus: Kopieren Sie die folgenden Zeilen und verwenden Sie das Tastenkürzel, um den vollständigen Liedtext zu erzeugen.

We're up all night 'til the sun
We're up all night to get some
We're up all night for good fun
We're up all night to get lucky

Datentyp des Tages: Dictionarys

Dictionarys ermöglichen es uns, Informationen zueinander in Beziehung zu setzen. Zum Beispiel interessiert uns in der Computerlinguistik oft, wie häufig bestimmte Wörter/Phrasen/Zeichen/... in einem Text vorkommen.

Dafür erstellen wir ein Dictionary, dessen Keys die Strings sind, die uns interessieren, und dessen Values die Häufigkeit jedes Strings im Text angeben.

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5}
print(frequencies)

Ab der Pythonversion 3.7 behalten Dictionarys immer die Reihenfolge, in der die Elemente eingefügt wurden. In früheren Pythonversionen können wir uns nicht darauf verlassen, dass das so ist. Das spielt dann eine Rolle, wenn wir z.B. mit einer for-Schleife durch das Dictionary iterieren wollen.

Hier sehen Sie, dass Python Dictionarys für identisch hält, wenn...

  1. sie die gleichen Keys enthalten
  2. und dabei den Keys jeweils die gleichen Werte zugeordnet werden.
In [ ]:
freq1 = {"dog": 3, "cat": 5}
freq2 = {"cat": 5, "dog": 3}
print(freq1 == freq2)

Die Informationen, die in einem Dictionary gespeichert sind, können wir abrufen, indem wir den Key angeben, der uns interessiert. Die Rückgabe ist dann der Wert, der zu diesem Key im Dictionary gespeichert ist. Die Syntax dafür ist <dictionary>[key].

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5}
print(frequencies["und"])

Ist ein Key nicht vorhanden, tritt ein Fehler auf:

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5}
print(frequencies["weil"])

Dictionarys sind, genau wie Listen, ein veränderlicher Datentyp (mutable). Um einen Wert ins Dictionary einzufügen, schreiben wir:

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5}

print(frequencies)          # bisheriger Inhalt des Dictionarys
frequencies["weil"] = 15    # dem Schlüssel "weil" soll jetzt der Wert 15 zugeordnet
                            # werden
print(frequencies)          # Dictionary mit zusätzlichem Schlüssel-Wert-Paar

Achtung: Jeder Schlüssel kann in einem Dictionary nur genau einmal vorkommen. Es gilt immer der zuletzt definierte Wert für den Schlüssel.

Und schließlich können wir auch durch Dictionarys iterieren. Die for-Schleife beginnt fast genauso wie bei Listen. Das aktuelle Element ist immer ein Schlüssel aus dem Dictionary. Wir können also beispielsweise alle Schlüssel-Wert-Paare nacheinander ausgeben:

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5, "weil": 15}

for word in frequencies:
    print("Wort: " + word)
    print("Häufigkeit: " + str(frequencies[word]))

Als Schlüssel für Dictionarys sind nur unveränderliche Datentypen erlaubt. Meistens benutzen wir Strings oder Zahlen. Listen sind als Werte möglich, aber nicht als Keys:

In [ ]:
freq3 = {"yes": [1,2,3], "no": [4,5,6]}
print(freq3)
In [ ]:
freq4 = { [1,2]: "yes", [4,5]: "no"}

Für das Beispiel, in dem Worthäufigkeiten gezählt werden sollen, brauchen wir Strings für die Wörter und Integers für die Häufigkeiten. Als Schlüssel sollten wir die Wörter wählen.

Es gibt mehrere Möglichkeiten, die Inhalte eines Dictionarys explizit zu sortieren: Entweder nach der Default-Sortierreihenfolge der Keys, oder nach der Sortierreihenfolge der Values.

Aufgabe

  1. Führen Sie die folgenden for-Schleifen aus und finden Sie heraus, welche Sortierung jedes Codebeispiel erzeugt.
In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5, "weil": 15}

print(frequencies)
for word in sorted(frequencies):
    print(word + "\t" + str(frequencies[word]))
In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5, "weil": 15}

print(frequencies)
for word in sorted(frequencies, key=frequencies.get):
    print(word + "\t" + str(frequencies[word]))
In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5, "weil": 15}

print(frequencies)
for word in sorted(frequencies, key=frequencies.get, reverse=True):
    print(word + "\t" + str(frequencies[word]))

Wenn wir uns nur für die Keys oder nur für die Values in einem Dictionary interessieren, können wir darauf mit den folgenden Befehlen zugreifen.

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5, "weil": 15}

print(frequencies.keys())
print(frequencies.values())

Die Ergebnisse dieser Befehle können wir in Listen umwandeln, damit wir Listenoperationen darauf anwenden können (z.B. Indexing und Slicing).

In [ ]:
frequencies = {"und": 12, "oder": 17, "nicht": 5, "weil": 15}

print(list(frequencies.keys())[:2])

Dabei müssen wir beachten, dass die Reihenfolge der Keys gegebenenfalls nicht vorhersehbar ist, weil Dictionarys ein unsortierter Datentyp sein können.

User-Input während der Laufzeit

Im folgenden Code-Beispiel wird ein Dictionary erstellt, indem Sie während der Laufzeit des Programms die Antworten auf einzelne Fragen eingeben. Eingaben während der Laufzeit werden mit dem Befehl input() abgefragt, das Ergebnis kann in einer Variable gespeichert werden. Die Eingabe wird mit Enter bestätigt.

Führen Sie das Programm aus und beobachten Sie, wie der Inhalt des Dictionarys sich in jedem Schleifendurchlauf ändert.

In [ ]:
datentypen = ["Strings", "Listen", "Zahlen", "Dictionarys"]
mutability = {}    # leeres Dictionary wird hier erstellt und unten nach und nach 
                   # gefüllt

for typ in datentypen:
    print("Sind " + typ + " veränderlich?")
    
    antwort = input()
    
    mutability[typ] = antwort
    print("Ihre bisherigen Antworten: " + str(mutability))

Die input()-Funktion kann auch mit einem Parameter in Form eines Strings ausgeführt werden. Dann erscheint beim Ausführen des Programms ein Prompt, der dem übergebenen String entspricht.

In [ ]:
# ohne Prompt
print("Ihre Nachricht (ohne Prompt): ")
message = input()
print(message)

# mit Prompt
message = input("Ihre Nachricht (mit Prompt): ")
print(message)

Zufallszahlen

Manchmal wollen wir zufällige Elemente aus einer Kollektion auswählen, z.B. weil nach dem häufigsten Wort in einem Text gesucht wird, es aber mehrere Wörter gibt, die mit der gleichen höchsten Häufigkeit vorkommen. Die zufällige Auswahl wird vom Modul random übernommen.

Module sind externe Pythonprogramme, die wir in unseren Code importieren können, um auf die Funktionen dort zugreifen zu können. Dazu schreiben wir am Anfang unseres Codes: import <modulname>

Danach können wir die Funktionen aus dem Modul verwenden. Damit der Interpreter weiß, wo die Funktionen definiert sind, schreiben wir bei jeder Verwendung auch den Namen des Moduls dazu.

Zum Beispiel geben wir eine zufällige Zahl zwischen 1 und 10 (beide inklusive) aus. Führen Sie die Zelle mehrmals aus (mit Ctrl + Enter), um zu sehen, dass jedes Mal eine andere Zahl gewählt wird:

In [ ]:
import random     # Modul random importieren
zahl = random.randint(1,10)  # Zufallszahl erzeugen
print(zahl)

Eine weitere Methode aus dem random-Modul, die wir benutzen, ist random.choice(). Damit wird ein zufälliges Element aus einer Kollektion gewählt.

In [ ]:
import random

words = ["Since", "I", "left", "you", "mine", "eye", "is", "in", "my", "mind"]
zufallswort = random.choice(words)
print(zufallswort)

Zusammenfassung

Sie haben heute gelernt,

  • Dictionarys zu erstellen
  • Die Werte aus Dictionarys abzufragen oder neu hinzuzufügen
  • Die Wertpaare in einem Dictionary nach den Keys oder Values sortiert zu verarbeiten
  • Nutzereingaben während des Programms abzufragen
  • Zufallszahlen zu erzeugen