Strings: Slicing, Methoden, Formatierung, Encoding

Track Python · PCAP-Fundament · ca. 50 Min.

Worum es geht

Strings kennst du aus JS/TS. In Python sind sie ähnlich, aber nicht gleich: Es gibt Slicing statt substring und slice, Methoden mit anderen Namen, f-Strings statt Template-Literals und einen sauberen Unterschied zwischen Text (str) und Bytes (bytes). Laut Glossar macht das Thema Strings in der PCAP fast ein Fünftel der Punkte aus. Nach dieser Lektion kannst du Slicing und Methodenketten im Kopf auswerten, Texte formatieren und erklären, warum ein Umlaut in UTF-8 zwei Bytes belegt, aber nur ein Zeichen ist.

Ablauf: erst die Übersetzung JS/TS nach Python, dann fünf kleine Schritte mit lauffähigem Code, dann fünf Übungen.

Von JS/TS her gedacht

Thema JS/TS Python
Teilstring s.slice(1, 4) s[1:4]
Umdrehen s.split("").reverse().join("") s[::-1]
Letztes Zeichen s.at(-1) s[-1]
Index außerhalb s[99] ergibt undefined s[99] wirft IndexError
Template `${name} ist ${n}` f"{name} ist {n}"
Anführungszeichen ', ", ` ' und " sind gleichwertig, kein Backtick
Mehrzeilig Template-Literal mit Backticks """..."""
Verbinden arr.join("-") (Methode der Liste) "-".join(arr) (Methode des Trenners)
Veränderbar? nein nein, jede Methode liefert einen neuen String

Der größte Stolperstein ist join. Beide Sprachen, derselbe Gedanke:

// TypeScript: join gehört zum Array
["a", "b", "c"].join("-");   // "a-b-c"
"Python".slice(1, 4);        // "yth"

Die Ausgabe lautet a-b-c und yth. Wie die Klammern [1:4] genau arbeiten, zeigt Schritt 1.

Konzept in kleinen Schritten

Schritt 1: Indizes und Slicing

Ein String ist eine Folge von Zeichen (sequence). Jedes Zeichen hat einen Index, von vorn ab 0, von hinten ab -1.

Die Regel für s[start:stop:step]:

  • start ist enthalten, stop ist ausgeschlossen. Die Länge des Ausschnitts ist also stop - start.
  • Fehlt ein Wert, gilt Anfang, Ende bzw. Schrittweite 1.
  • Mit negativem step läuft Python rückwärts. Dann bedeuten fehlende Werte “vom Ende” und “bis zum Anfang”.
  • Slicing wirft nie einen Fehler, auch wenn die Grenzen außerhalb liegen. Ein einzelner Index schon.

Und Strings sind unveränderbar (immutable). Du kannst ein Zeichen nicht überschreiben:

Schritt 2: Methoden

Weil Strings unveränderbar sind, verändert keine Methode den Original-String. Jede gibt einen neuen zurück. Wer das Ergebnis nicht speichert, hat nichts getan.

Die wichtigsten Methoden (Quelle: Glossar):

Gruppe Methoden Hinweis
Schreibweise upper(), lower(), capitalize(), title(), swapcase() capitalize macht den Rest klein
Aufräumen strip(), lstrip(), rstrip() ohne Argument: Whitespace
Zerlegen split(sep), partition(sep) split() ohne Argument trennt an beliebigem Whitespace
Verbinden sep.join(liste) Trenner steht vor dem Punkt
Ersetzen replace(alt, neu) ersetzt alle Vorkommen
Suchen find(x), index(x), count(x) find liefert -1, index wirft ValueError
Prüfen startswith, endswith, isalpha, isdigit, isalnum, isspace, islower, isupper liefern bool
Auffüllen center(n), ljust(n), rjust(n), zfill(n) "7".zfill(3) ergibt "007"

Der Unterschied zwischen split() und split(" ") ist eine beliebte Falle:

Methoden lassen sich verketten (method chaining), wie in JS: " Hi ".strip().upper() ergibt "HI".

Schritt 3: Formatierung

Es gibt drei Wege. Der moderne ist der f-String (formatted string literal), das Gegenstück zu Template-Literals.

  • Nach dem Doppelpunkt steht die Formatangabe (format spec). 03d heißt: ganze Zahl (d), mindestens 3 Stellen, links mit Nullen aufgefüllt. Ist die Zahl länger, wird nichts abgeschnitten.
  • str(x) ist für Menschen gedacht, repr(x) für Entwickler. Bei Strings erkennst du den Unterschied an den Anführungszeichen:

In diesen Lektionen lassen wir repr oft in Ausgaben mitlaufen, damit leere Strings und Leerzeichen sichtbar werden.

Schritt 4: Escape, Raw-Strings, Quotes

  • Escape-Zeichen (escape sequences): \n Zeilenumbruch, \t Tabulator, \\ Backslash, \" und \' Anführungszeichen. Jede dieser Folgen ist ein Zeichen.
  • Raw-String (raw string): r"C:\neu" behandelt Backslashes als normale Zeichen. Praktisch für Windows-Pfade und reguläre Ausdrücke.
  • Mehrzeilig: """...""" erlaubt Zeilenumbrüche im Text.

Im normalen String ist \n ein einziges Zeilenumbruch-Zeichen. Darum hat er nur 5 Zeichen, der Raw-String 6.

Schritt 5: Vergleich, Codepoints, Encoding

Strings werden zeichenweise nach Unicode-Codepoint verglichen, nicht nach Alphabet.

Text (str) und Bytes (bytes) sind in Python zwei verschiedene Typen. Mit encode wird aus Text Bytes, mit decode wieder Text:

len(string) zählt Zeichen, len(bytes) zählt Bytes. Ein Umlaut belegt in UTF-8 zwei Bytes.

Falle: die Prüfungs- und Praxisklassiker

  1. Ergebnis nicht gespeichert: s.upper() allein ändert s nicht.
  2. Stop ist ausgeschlossen: s[2:6] hat vier Zeichen, nicht fünf.
  3. Einzelner Index vs. Slice: s[99] wirft IndexError, s[99:] ergibt "".
  4. split() vs. split(" "): nur die erste Variante schluckt mehrfache Leerzeichen.
  5. join am falschen Objekt: liste.join("-") gibt es nicht, es heißt "-".join(liste).
  6. Vergleich nach Codepoint: "a" > "B" ist True, "10" < "9" ist True.
  7. sorted(s) liefert eine Liste, keinen String.
  8. Zeichen vs. Bytes: len("ä") ist 1, len("ä".encode("utf-8")) ist 2.

Übungen

Übung 1: Slicing vorhersagen

Der Code steht fest, du musst nur die Werte vorhersagen:

s = "Programmierung"
a = s[2:6]
b = s[-3:]
c = s[::-3]
d = s[10:100]

Trage ein Tupel (a, b, c, d) ein.

Bei c geht Python rückwärts: Es startet beim letzten Zeichen und nimmt jeweils das dritte. Und bei d: Was passiert mit einem Slice, dessen Grenzen über das Ende hinausgehen?

antwort = ("ogra", "ung", "grmrr", "rung")
antwort

Übung 2: Methodenkette schreiben (Lücke füllen)

Schreibe slug(text). Sie macht aus einem beliebigen Text einen URL-Baustein: alles klein, am Anfang und Ende kein Whitespace, und jede zusammenhängende Folge von Whitespace (Leerzeichen, Tabs, Zeilenumbrüche) wird zu genau einem -. Beispiel: " Hallo Welt\t" wird zu "hallo-welt".

Du brauchst zwei Dinge: eine Methode, die Text in Wörter zerlegt, ohne dass leere Einträge entstehen, und eine, die die Wörter wieder mit einem Trenner zusammensetzt. Wer hält bei join den Trenner?

def slug(text):
    return "-".join(text.lower().split())

slug

Übung 3: Escape, Raw, Vergleich und Unveränderbarkeit vorhersagen

Der Code steht fest:

a = len(r"C:\neu")
b = len("C:\neu")
c = repr("hi")
d = "10" < "9"
try:
    "abc"[0] = "x"
    e = None
except Exception as ex:
    e = type(ex).__name__

Trage ein Tupel (a, b, c, d, e) ein. c ist ein String, e der Name der Exception als String.

Zähle bei a und b die Zeichen einzeln: Wann ist \n ein Zeichen und wann zwei? Bei c zählt jedes Zeichen des Ergebnisses, auch die Anführungszeichen. Bei d vergleicht Python zeichenweise, nicht als Zahlen. Bei e überlege, was eine Zuweisung an ein Zeichen eines unveränderbaren Typs auslöst.

antwort = (6, 5, "'hi'", True, "TypeError")
antwort

Übung 4: Formatieren

Schreibe etikett(name, nr). Sie liefert den Namen in Großbuchstaben, einen Bindestrich und die Nummer mindestens dreistellig mit führenden Nullen. Beispiel: etikett("kabel", 7) ergibt "KABEL-007". Ist die Nummer länger als drei Stellen, bleibt sie vollständig erhalten.

Du kannst die Nummer in einem f-String direkt mit einer Formatangabe nach dem Doppelpunkt aufbereiten. Schau in Schritt 3, was 03d bewirkt. Alternativ gibt es eine Auffüll-Methode, die aber nur auf Strings arbeitet.

def etikett(name, nr):
    return f"{name.upper()}-{nr:03d}"

etikett

Übung 5: Zeichen, Bytes und Sortierung

Schreibe profil(text). Sie liefert ein Tupel aus drei Werten: (1) die Anzahl Zeichen, (2) die Anzahl Bytes in UTF-8, (3) die Zeichen des Textes nach Codepoint sortiert, zusammengesetzt zu einem String. Beispiel: profil("Bä") ergibt (2, 3, "Bä").

Zeichen zählt len auf dem Text, Bytes zählt len auf etwas anderem. Und sorted liefert nicht den Typ, den du am Ende brauchst. Wie machst du daraus wieder einen einzelnen String?

def profil(text):
    return (len(text), len(text.encode("utf-8")), "".join(sorted(text)))

profil

Merksatz und Prüfstein

Merksatz: Strings sind unveränderbar, Slicing schließt stop aus und wirft nie einen Fehler, und len zählt Zeichen, nicht Bytes.

Prüfstein (offene Frage): Erkläre in eigenen Worten, warum "10" < "9" in Python True ist und "a" > "B" ebenfalls, und was du tun müsstest, damit "10" und "9" als Zahlen verglichen werden.

Quelle: quellen/python-glossar-pcap-pcpp1.md, Abschnitt “Strings” (Indizes und Slicing, Methoden, Formatierung, Escape/Raw-Strings/Quotes, Vergleich/Codepoints/Encoding). Hinweis: Die Formatangabe 03d steht im Glossar, {x=} ebenfalls; Gewichtung laut Glossar (Tabelle Prüfungsblöcke, Stand 1. Oktober 2026): Block 3 Strings, 8 Fragen, 18 %, also “fast ein Fünftel”. Der Vergleich s.at(-1) und weitere JS-Beispiele sind Vergleichshilfen und nicht Teil der Quelle.