Zeichenketten und einfache Skripte
Overview
Teaching: 110 min
Exercises: 0 minQuestions
Wie kann ich Zeichenketten in Python eingeben und darstellen?
Wie kann ich auf diese oder Teile davon zugreifen?
Was muss ich beim Ausführen von Python-Skripten beachten?
Objectives
Verstehen des Datentyps
str
Typs von Python
Zeichenketten als Wert definieren
Zeichenketten oder Strings sind Sequenzen von Zeichen die zur Repräsentation von Text verwendet werden.
Sie werden in Python gekennzeichnet mit umschließenden '
oder "
. Folgende Befehle sind also äquivalent:
text = 'Ein Brötchen kostet 25 Cent'
text = "Ein Brötchen kostet 25 Cent"
Variablen mit einem Textwert haben den Typ str
:
type(text)
<class 'str'>
Man kann allerdings nicht einen String mit '
beginnen und dann mit "
schließen, oder umgekehrt
text = 'Ein Brötchen kostet 25 Cent"
File "<stdin>", line 1
text = 'Ein Brötchen kostet 25 Cent"
^
SyntaxError: EOL while scanning string literal
Zugriff auf Teile von Strings
Jedem Zeichen in einem String ist ein Index zugewiesen, der seiner Position in der Zeichenkette entspricht. Gezählt wird ab 0 und Leerzeichen werden nicht übersprungen:
E | i | n | B | r | ö | t | c | h | e | n | k | o | s | t | e | t | 2 | 5 | C | e | n | t | ||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
Der in text
gespeicherte String hat eine Länge von 27 Zeichen. Diese berechnen wir in Python mit der len
Funktion:
len(text)
Es ist möglich auf Abschnitte bzw. einzelne Zeichen des Strings über den Index und eckige Klammern zuzugreifen. Probieren Sie es selbst:
text[6]
Zeichenkodierung in Python
Wir erkennen, dass Python keine Probleme mit Umlauten hat. Das liegt daran, dass in Python 3 (im Gegensatz zu Python 2) Strings standardmäßig in Unicode kodiert sind.
Frage(n)
Indexierung funktioniert auch mit negativen Zahlen:
text[-3]
Was erhalten Sie für den negativen index
[-3]
, wie geht Python in solchen Fällen vor?Lösung
'e'
Python gibt nicht das 3. Zeichen von vorne, sondern das 3. Zeichen vom Ende des Textes aus.
Frage(n)
Was passiert in folgendem Fall? Bevor sie es ausführen, was erwarten Sie?
text[30]
Lösung
Sie erhalten eine Fehlermeldung, dass der Index außerhalb des korrekten Bereichs für diesen Textwert war.
Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: string index out of range
Einen Abschnitt eines Strings (Substring) erhalten wir über einen Index [a:b]
wobei a
der Index des ersten Zeichens ist und b
das Ende des Abschnitts beschreibt. a
ist inklusiv, der a
-te Buchstabe ist also selbst im Substring enthalten, b
ist dagegen exklusiv, der b
-te Buchstabe ist also nicht enthalten, nur der Buchstabe (mit Index b-1
) davor.
text[0:3]
'Ein'
Frage(n)
Probieren Sie anhand eines Beispielstrings mit der Länge L folgende Dinge aus:
- Was passiert, wenn Sie a, b oder beide Grenzen weglassen?
- Was passiert, wenn b > Länge des Strings
- Was passiert, wenn a > Länge des Strings
- Was passiert, wenn a > b? Was wenn a == b?
- Was passiert, wenn a > 0 und b < 0?
- Was passiert, wenn a < 0 und b > 0?
Lösung
Wenn die erste Grenze a weggelassen wird, wird implizit das erste Zeichen (0) als Start angenommen.
text[:3]
'Ein'
Wenn dagegen die zweite Grenze b weggelassen wird, wird implizit das letzte Zeichen als Ende angenommen.
text[23:]
'Cent'
Das Weglassen beider Grenzen entspricht dem ganzen String, ohne Einschränkung für Beginn und Ende.
text[:]
'Ein Brötchen kostet 25 Cent'
Der End-Index wird immer implizit auf die Länge des Strings begrenzt. Ist der Größer, wird der String nur bis zum Ende des Strings zurück gegeben. Ist hingegen der Start-Index größer als die Länge des Texts, wird nur der leere String zurück gegeben.
text[4:123]
'Brötchen kostet 25 Cent'
text[123:]
''
Analog dazu, wird auch der leere String ausgegeben, wenn der Start-Index größer oder gleich dem End-Index ist.
text[123:4]
''
text[4:4]
''
Wenn der Start-Index a größer gleich 0 ist und der End-Index b negativ, wird der Teilstring vom Zeichen mit dem Index a bis zum b. Zeichen zählend vom Ende des Texts zurückgegeben.
text[4:-8]
'Brötchen kostet'
Das geht aber nur, solange der negative Wert nicht über den Anfang des mit a beginnenden Teilstrings “hinausragt”.
Wenn a < 0 und b > 0 ist, wird normalerweise eine leerer String zurückgegeben. Wenn das Ende b aber größer ist als die Länge des Strings, ist der Ausdruck äquivalent zu
text[-a:]
und es werden die letzten a Zeichen des Teilstrings ausgeben.text[-4:10]
''
text[-4:100]
'Cent'
Wie Sie sehen, können negative Index sehr schnell sehr kompliziert und unerwartete Semantik mit sich bringen. Die Python-Dokumentation zu “Sequences” hat weitere Beispiele für komplexe Zugriffe über Indexes: https://docs.python.org/3.7/library/stdtypes.html?highlight=sequence#sequence-types-list-tuple-range. Solche komplexen Konstrukte werden ohne genaue Kenntnis der Python-Dokument sehr schnell sehr schwer verständlich und sollten vermieden werden.
Übung
Beschäftigen wir uns weiter mit dem oben erwähnten String, den wir in text gespeichert haben. Nehmen Sie an, Sie wollen die für Sie wesentliche Information aus Werbetexten wie „Ein Brötchen kostet 25 Cent“ extrahieren. Sie interessieren sich nur für das Produkt („Brötchen“) und den Preis („25 Cent“).
Vervollständigen Sie das folgende Codefragment so, dass diese Daten in den beiden Variablen
what
undhowmuch
gespeichert werden.what = text howmuch = text
Lösung
what = text[4:12] howmuch = text[20:len(text)]
print
-Funktion
In der interaktiven Konsole kann man den Namen einer Variable als Befehl eingeben und bekommt deren Wert angezeigt. Sobald wir nicht mehr interaktiv in der Konsole, sondern mit Python-Skripte arbeiten, wird uns das nicht mehr weiterhelfen. Wir benötigen eine Funktion, mit der wir Variablen explizit ausgeben können.
Die Funktion print
nimmt als Eingabe Daten vom Typ String und gibt diese auf der Konsole aus. Das einzige Argument der Funktion wird dabei in Klammern angegeben. Versuchen Sie es selbst:
print(what)
Sie können print
auch mehrere Strings übergeben.
Diese werden durch ein Zeichen (Standard: Leerzeichen) getrennt ausgegeben. Das Trennzeichen kann über den Parameter sep
manipuliert werden.
sep
ist ein benannter Parameter, das heißt man gibt in den Klammern nicht nur den Wert an, sondern schreibt sep=
davor.
print(what,howmuch)
Brötchen 25 Cent
print(what,howmuch,sep=";")
Brötchen;25 Cent
Ausführen mehrerer Anweisungen in einem Skript
Wie wir bereits im 1. Kapitel gesehen haben, können wir anstatt Anweisungen für ein Programm interaktiv in der Konsole auszuführen sie auch in eine Textdatei mit der Endung .py
schreiben.
Der Befehl python3 dateiname.py
auf der Konsole führt diese Anweisungen dann hintereinander aus.
Wird das Programm beendet, werden auch alle Variablen vergessen.
Jeder Aufruf vom Python-Interpreter startet also immer ohne definierte Variablen, erst durch die einzelnen Ausführungsschritte im Skripts werden die Variablen definiert und mit Werten belegt.
Bei der Entwicklung testet man oft kurze Code-Stücke in der interaktiven Konsole, die man dann in ein Skript überträgt.
Windows
Windows enthält standardmäßig kein Python und die Unterscheidung in Version 2 und 3 ist daher nicht so relevant. Nach einer systemweiten Installation und der Eintragung von der Python-Installation in die Systemvariable
PATH
oder mitconda activate
kann man daher unter Windows mit dem Befehlpython
(also ohne die Versionsnummer „3“) auf der Kommandozeile starten.
Übung
Nutzen Sie einen Texteditor um ein Programm zu schreiben, dass folgende Anweisungen hintereinander ausführt und führen sie dies aus.
- Berechne die Summe von 100 und 123
- Gebe die Zeichenkette “100+123=???” wobei „???“ für das Ergebnis steht.
Lösung
# Dieser Text steht in der Datei summe.py summe = 100+123 print("100+123",summe,sep="=")
python3 summe.py
100+123=223
Strings verketten
Wenn wir zwei Strings miteinander zu einem neuen String verbinden wollen (konkatenieren), so nutzen wir den „+“-Operator, den wir schon von den Zahlenoperationen kennen.
stem_1 = 'Haus'
stem_2 = 'boot'
comp = stem_1 + stem_2
print(comp)
Hausboot
Wollen wir eine Zeichenkette n mal vervielfachen, so können wir sie einfach mit n multiplizieren:
result = 'Nomen'*10
print(result)
NomenNomenNomenNomenNomenNomenNomenNomenNomenNomen
Strings können aus anderen Datentypen über die Konvertierungsfunktion str(val)
erzeugt werden.
Damit kann man z.B. auch einen String mit einer Zahl verketten
zahl = 13+13
result = "Die Zahl ist " + str(zahl)
print(result)
Die Zahl ist 26
String-Methoden
Wir wollen uns einen Überblick über die wichtigsten Methoden für String-Variablen ansehen.
Aber was sind denn nun wieder Methoden?
In dieser Episode nur so viel: Methoden sind Funktionen, die wir an einer Variable (genauer: einem Objekt) mit Hilfe eines .
direkt aufrufen.
Hier ein Beispiel:
var = "Huch"
print(var) # Funktion
var.strip() # Methode
strip()
Diese Methode ist z. B. wichtig bei der Bereinigung unserer Eingabe. Sie entfernt Leerzeichen, Zeilenumbrüche (\n in Linux), Tab-Einrückungszeichen (\t) und andere White-Space-Zeichen am Anfang und Ende des Strings. Sie verändert nicht die Variable, an der sie aufgerufen wird, sondern gibt einen neuen String zurück.
txt = "\tWas macht strip()? "
txt_no_whitespaces = txt.strip()
print("|" + txt + "|")
| Was macht strip()? |
print("|" + txt_no_whitespaces + "|")
|Was macht strip()?|
find(seq)
und rfind(seq)
Wenn wir eine Sequenz von 1 und mehr Zeichen in einem String suchen wollen, geben uns diese Methoden die Stelle (als Integer) im String zurück,
an der die Sequenz beginnt.
find(seq)
gibt uns den ersten Treffer von links, rfind(seq)
entsprechend von rechts.
Ausgegeben wird die Stelle des ersten Zeichens der gesuchten Sequenz.
haystack = 'Heu Nadel Heu Heu Nadel Heu'
l = haystack.find('Nadel')
r = haystack.rfind('Nadel')
print(l,r)
4 18
Übung
Bearbeiten Sie den folgenden Abschnitt so, dass aus
info
nur der Text zwischen „Achtung“ und „egal“ ausgegeben (über dieinfo = "bla bla bla Achtung Wichtig egal bla bla bla" # Ihr Code:
Lösung
wichtig_l = info.find("Achtung") + len("Achtung") wichtig_r = info.rfind("egal") print(info[wichtig_l:wichtig_r].strip())
Wichtig
replace(is, willbe)
Mit dieser Methode wird eine Zeichensequenz in einem String an jeder Stelle ihres Vorkommens durch eine andere ersetzt. Das Ergebnis wird als neuer String zurückgegeben.
In folgendem Beispiel sollen aus dem Input-String „ß“ und Umlaute entfernt und durch Alternativen ersetzt werden:
messy_input = "Sie wohnen in der Hauptstraße. Das ist ungewöhnlich."
clean_input = messy_input.replace("ß","ss").replace("ö","oe").replace("ä","ae").replace("ü","ue")
print(clean_input)
Sie wohnen in der Hauptstrasse. Das ist ungewoehnlich.
Frage(n)
- Warum kann
replace
einfach mehrmals hintereinander aufgerufen werden?- Was passiert, wenn ein String eine zu ersetzende Zeichensequenz nicht enthält?
Lösung
Die Methode
replace
liefert als Rückgabewert wieder einen neuen String zurück und auf Strings kann man die Methodereplace
ausführen. Man muss nicht zwingend den Rückgabewert in eine Variable zwischenspeichern, um ihn zu nutzen.Wenn die gesuchte Zeichensequenz nicht vorkommt, wird der unveränderte Original-String zurückgegeben.
messy_input.replace("Berlin", "Brandenburg")
'Sie wohnen in der Hauptstraße. Das ist ungewöhnlich.'
Übung
Schreiben Sie einen „Übersetzer“, der den String german ins Englische übersetzt.
german = "Die Katze ist schwarz" # Ihr Code engl =
Überlegen Sie kurz, ob dieses Vorgehen generell, also für eine beliebige deutsche Eingabe, sinnvoll ist.
Lösung
Wir können im Moment nur kontextunabhängig einzelne Strings ersetzen. Für das konkrete Beispiel reicht das schon, auch wenn wir natürlich kein Zugriff auf ein Lexikon oder syntaktische und semantische Informationen haben und nicht einmal Wörter erkennen oder sogar die Wortstellung umschreiben können.
german = "Die Katze ist schwarz" engl = german.replace("Die", "The").replace("Katze", "cat").replace("ist", "is").replace("schwarz", "black") print(engl)
The cat is black
startswith
und endswith
Die beiden Funktionen überprüfen, ob ein String mit einem Prefix beginnt oder einem Suffix endet.
satz = "Ein Wort ist kein Satz."
print(satz.startswith("Ein"))
print(satz.endswith("!"))
True
False
Kernpunkte
Strings sind Sequenzen von Zeichen auf die über einen Index zugegriffen werden kann.
Es gibt Methoden, die Operationen auf diesen Zeichenketten ausführen, wie z.B. finden und ersetzen.
Variablen werden nur innerhalb eines Aufrufs des Python-Interpreters gespeichert.