zurück rauf weiter Englisch Index

Kapitel 7

Rohübersetzung -- bitte um Rückmeldungen über Fehler und Unklarheiten an glingl@aon.at

Strings

7.1 Ein zusammengesetzter Datentyp

Bis jetzt haben wir drei Datentypen kennengelernt: int, float und string. String ist qualitativ verschieden von den anderen beiden, weil Strings aus kleineren Bausteinen zusammengesetzt sind     aus Zeichen (character).

Typen, die kleinere Bausteine umfassen werden zusammengesetzte Datentypen oder auch strukturierte Datentypen genannt. Je nach dem was man gerade tut, möchte man einen zusammengesetzten Datentyp entweder als einzelnes Ding behandeln oder auf seine Bestandteile zugreifen. Es ist daher nützlich, hier beide Möglichkeiten zur Verfügung zu haben.

Der Eckige-Klammer-Operator wählt ein einzelnes Zeichen aus dem String aus.

>>> fruit = "banana"
>>> letter = fruit[1]
>>> print letter

Der Ausdruck fruit[1] entnimmt das Zeichen Nummer 1 aus fruit. Die Variable letter verweist auf das Ergebnis. Wenn wir letter ausgeben, erleben wir eine Überraschung:

a

Der erste Buchstabe von "banana" ist nicht a. Außer man ist ein Informatiker. Aus perversen Gründen beginnen Informatiker immer bei 0 zu zählen. Der 0.te ("nullte") Buchstabe von "banana" ist b. Der 1. ("erste") Buchstabe ist a und der 2. ("zweite") Buchstabe ist n.

Möchte man den nullten Buchstaben eines Strings haben, tut man einfach eine 0, oder irgendeinen Ausdruck, der den Wert null ergibt, in die eckigen Klammern.

>>> letter = fruit[0]
>>> print letter
b

Den Ausdruck in den eckigen Klammern nennt man einen Index. Ein Index legt ein Element einer geordneten Menge fest, in unserem Fall der Menge der Buchstaben in einem String. Der Index gibt einfach an, welchen man meint. Er kann ein beliebiger Ganzzahl-Ausdruck sein.

7.2 Länge

Die len Funktion gibt die Anzahl der Zeichen in einem String zurück:

>>> fruit = "banana"
>>> len(fruit)
6

Um den letzten Buchstaben eines Strings zu erhalten, könnte man versucht sein etwa folgendes auszuprobieren:

length = len(fruit)
last = fruit[length]       # FEHLER!

Das wird aber nicht funktionieren. Es verursacht den Laufzeitfehler IndexError: string index out of range. Das liegt daran, dass es im Wort "banana" keinen 6. Buchstaben gibt. Weil wir bei 0 zu zählen beginnen, werden die 6 Buchstaben von 0 bis 5 durchnummeriert. Um das letzte Zeichen zu erhalten, müssen wir 1 von der Länge abziehen:

length = len(fruit)
last = fruit[length-1]

Alternativ können wir auch negative Indizes verwenden, die vom Ende des Strings zurück zählen. Der Ausdruck fruit[-1] liefert den letzten Buchstaben, fruit[-2] den vorletzten und so weiter.

7.3 Durchlauf mit der for Schleife

Viele Berechnungen beinhalten die buchstabenweise Verarbeitung von Strings. Oft beginnen sie am Anfang, wählen ein Zeichen nach dem anderen aus, machen irgendetwas damit und fahren so bis zum Ende fort. Dieses Verarbeitungsmuster nennen wir einen Durchlauf. Ein Weg um einen Durchlauf zu kodieren ist, eine while-Schleife zu verwenden:

index = 0
while index < len(fruit):
  letter = fruit[index]
  print letter
  index = index + 1

Diese Schleife durchläuft den String und schreibt jeden Buchstaben in eine eigene Zeile. Die Schleifenbedingung ist index < len(fruit), daher wird die Bedingung falsch, wenn index gleich der Länge des Strings ist und der Schleifenkörper wird dann nicht mehr ausgeführt. Der letzte Buchstabe, auf den zugegriffen wird, ist der mit dem Index len(fruit)-1, welcher ja der letzte Buchstabe in dem String ist.

Übung: schreibe eine Funktion, die einen String als Argument übernimmt und die Buchstaben von hinten nach vorne, einen pro Zeile ausgibt

Einen Index zu verwenden um einen Satz von Werten zu durchlaufen ist so gebräuchlich, dass Python dafür eine alternative, einfachere Syntax bereitstellt     die for Schleife:

for char in fruit:
  print char

Bei jedem Schleifendurchgang wird der nächste Buchstabe im String der Variablen char zugewiesen. Die Schleife wird so lange fortgesetzt, bis keine Buchstaben mehr übrig sind.

Das folgende Beispiel zeigt, wie man Verkettung und eine for Schleife benützen kann um eine ABC-Reihe zu erzeugen."ABC-Reihe" meint eine Reihe (Folge) oder Liste, in der die Elemente in alphabetischer Ordnung auftreten. Da gibt es z. B. in Robert McCloskeys Buch Make Way for Ducklings die Namen der ducklings Jack, Kack, Lack, Mack, Nack, Ouack, Pack, and Quack. Die folgende Schleife gibt diese Namen in der richtigen Reihenfolge aus:

prefixes = "JKLMNOPQ"
suffix = "ack"

for letter in prefixes:
  print letter + suffix

Die Ausgabe des Programms ist:

Jack
Kack
Lack
Mack
Nack
Oack
Pack
Qack

Ganz ok ist das natürlich nicht, weil "Ouack" und "Quack" nicht richtig geschrieben sind.

Übung: modifiziere das Programm, um diesen Fehler zu beheben

7.4 String - Abschnitte

Einen Abschnitt eines Strings nennt man auch ein slice (eine Scheibe). Die Auswahl eines Abschnitts ist ähnlich der Auswahl eines einzelnen Zeichens:

>>> s = "Peter, Paul, and Mary"
>>> print s[0:5]
Peter
>>> print s[7:11]
Paul
>>> print s[17:21]
Mary

Der Operator [n:m] gibt den Teil des Strings zurück, der vom n-ten Buchstaben bis zum m-ten Buchstaben geht - den ersten eingeschlossen und den lezten ausgeschlossen. Dieses Verhalten widerspricht ein bisschen der Intuition; Man stellt sich vielleicht besser vor, dass die Indizes zwischen die Buchstaben zeigen, wie im folgenden Diagramm:

Wenn man den ersten Index (vor dem Doppelpunkt) wegläßt, beginnt der Abschnitt am Anfang des Strings. Läßt man den zweiten Index weg, geht der Abschnitt bis zum Ende des Strings. Somit:

>>> fruit = "banana"
>>> fruit[:3]
'ban'
>>> fruit[3:]
'ana'

Was glaubst du wird s[:] bedeuten?

7.5 Vergleich von Strings

Die Vergleichsoperatoren funktionieren auch mit Strings. So prüft man, ob zwei Strings gleich sind:

if word == "banana":
  print  "Yes, we have no bananas!"

Andere Vergleichsoperationen kann man verwenden, um Wörter in alphabetische Reihenfoge zu bringen:

if word < "banana":
  print "Your word," + word + ", comes before banana."
elif word > "banana":
  print "Your word," + word + ", comes after banana."
else:
  print "Yes, we have no bananas!"

Man sollte sich aber bewußt sein, dass Python Groß- und Kleinbuchstaben nicht so behandelt wie wir das gewohnt sind. Alle Großbuchstaben kommen nämlich vor allen Kleinbuchstaben. Das ergibt z. B.:

Your word, Zebra, comes before banana.

Normalerweise löst man dieses Problem, indem man Strings in ein Standardformat, z. B. nur Kleinbuchstaben, umwandelt bevor man den Vergleich durchführt. Ein Programm dazu zu bringen, zu erkennen, dass Zebras keine Früchte sind, ist schon schwierigeres Problem .

7.6 Strings sind unveränderbar

Es wäre naheliegend, den [] - Operator auf der linken Seite einer Wertzuweisung mit der Absicht zu verwenden, einen Buchstaben in einem String zu ändern. Zum Beispiel:

greeting = "Hello, world!"
greeting[0] = 'J'            # ERROR!
print greeting

Anstatt die Ausgabe Jello, world! zu erzeugen, liefert dieser Code aber nur einen Laufzeitfehler TypeError: object doesn't support item
assignment
.

Strings are immutable, which means you can't change an existing string. The best you can do is create a new string that is a variation on the original: Strings sind nicht veränderbar (engl.: immutable), das heißt, man kann einen existierenden String nicht verändern. Das beste, was man tun kann, ist einen neuen String zu erzeugen, der eine Variante des alten ist:

greeting = "Hello, world!"
newGreeting = 'J' + greeting[1:]
print newGreeting

Die Lösung wird hier so erreicht, dass wir einen neuen ersten Buchstaben mit einem Abschnitt von greeting verketten. Diese Operation bewirkt keine Veränderung der ursprünglichen Strings.

7.7 Eine Funktion namens find

Was macht die folgende Funktion?

def find(str, ch):
  index = 0
  while index < len(str):
    if str[index] == ch:
      return index
    index = index + 1
  return -1

In gewissem Sinne ist find das Gegenteil des [] - Operators. Anstatt zu einem gegebenen Index den entsprechenden Buchstaben herauszusuchen, nimmt es einen Buchstaben und findet den Index, wo sich der Buchstabe befindet. Wenn der Buchstabe überhaupt nicht vorkommt, gibt die Funktion -1 zurück.

Das ist das erste Beispiel, in dem eine return Anweisung innerhalb einer Schleife auftritt. Wenn str[index] == ch, dann gibt die Funktion sofort den Wert von index aus und bricht die Schleife frühzeitig ab.

Wenn der Buchstabe in dem String nicht vorkommt, beendet das Programm die Schleife normal und gibt danach -1 zurück.

Dieses Code-Muster nennt man manchmal einen "eureka" - Durchlauf, denn sobald wir gefunden haben, wonach wir suchen können wir "Eureka" rufen und aufhören weiter zu suchen.

Übung. ändere die find Funktion so ab, dass sie einen dritten Parameter hat: den Index im String, bei dem die Suche begonnen werden soll.

7.8 Schleifen und Zähler

Das folgende Programm zählt ab, wie oft der Buchstabe a in einem String vorkommt:

fruit = "banana"
count = 0
for char in fruit:
  if char == 'a':
    count = count + 1
print count

Diese Programm demonstriert ein anderes Code-Muster, einen sogenannten Zähler. Die Variable count wird mit 0 initialisiert und dann wird ihr Wert jedesmal um 1 erhöht, wenn ein a gefunden wurde. (Man sagt auch oft: die Variable wird inkrementiert. Das ist das Gegenteil von dekrementieren, wo der Wert der Variablen um 1 vermindert wird).

Übung: kapsle diesen Code in eine Funktion namens countLetters und verallgemeinere so, dass die Funktion zwei Parameter hat: den String und den Buchstaben
Übung: formuliere diese Funktion so um, dass sie die Drei-Parameter-Version von find aus der Übung davor verwendet, anstatt den String mit einer Schleife zu durchlaufen.

7.9 Der string Modul

Der string Modul enthält nützliche Funktionen, die Strings bearbeiten. Wie üblich, müssen wir den Modul importieren, befor wir ihn verwenden können:

>>> import string

Der string Modul enthält eine Funktion namens find, die das gleiche tut wie die Funktion die wir geschrieben haben. Um sie aufzurufen, müssen wir den Namen des Moduls angeben und den Namen der Funktion, wobei wir die Punkt-Schreibweise benützen:

>>> fruit = "banana"
>>> index = string.find(fruit, "a")
>>> print index
1

Dieses Beispiel demonstriert einen der Vorteile von Modulen     sie helfen Konflikte zwischen den Namen eingebauter Funktionen und den Namen benutzerdefinierter Funktionen zu vermeiden. Indem man die Punkt-Schreibweise verwendet kannman festlegen, welche Version von find man verwenden will.

Tatsächlich ist string.find allgemeiner als unsere Version. Erstens kann es Teilstrings finden und nicht nur Buchstaben:

>>> string.find("banana", "na")
2

Weiters übernimmt es ein zusätzliches Argument, dass den Index festlegt, mit bei dem die Suche beginnen soll:

>>> string.find("banana", "na", 3)
4

Oder es kann zwei zusätzliche Argumente übernehmen, die einen Bereich von Indizes festlegen:

>>> string.find("bob", "b", 1, 2)
-1

In diesem Beispiel schlägt die Suche fehl, weil der Buchstabe b in dem Indexbereich von 1 bis 2 (der ja 2 nicht mehr enthält) nicht vorkommt.

7.10 Klassifikation von Zeichen

Es ist oft erforderlich ein einzelnes Zeichen zu betrachten und zu prüfen, ob es ein Klein- oder ein Großbuchstabe ist oder ob es ein Buchstabe oder eine Ziffer ist. Der string Modul stellt einige Konstanten zur Verfügung, die für diese Zwecke nützlich sind.

Der String string.lowercase enthält alle Buchstaben, die das System als Kleinbuchstaben betrachtet. Ähnlich enthält string.uppercase alle Großbuchstaben. Probiere folgendes aus und sieh nach welches Ergebnis du erhältst:

>>> print string.lowercase
>>> print string.uppercase
>>> print string.digits

Wir können dieses Konstanten und find dazu benützen, Buchstaben zu klassifizieren. Wenn zum Beispiel find(lowercase, ch) einen anderen Wert als -1 zurückgibt, dann muß ch ein Kleinbuchstabe sein:

def isLower(ch):
  return find(string.lowercase, ch) != -1

Alternativ können wir auch vom in Operator Gebrauch machen, der feststellt ob ein Zeichen in einem String vorkommt:

def isLower(ch):
  return ch in string.lowercase

Eine weitere Alternative ist, den Vergleichsoperator zu benützen:

def isLower(ch):
  return 'a' <= ch <= 'z'

Wenn ch zwischen a und z liegt, muss es ein Kleinbuchsabe sein.

Übung: überlege, welche Version von isLower wohl die schnellste sein wird. Kannst du dir auch noch andere Gründe neben der Ausführungsgeschwindigkeit für die Bevorzugung dieser oder jener Version vorstellen?

Eine andere Konstante, die im string Modul definiert ist, wird dich vielleicht überraschen, wenn du sie dir ansiehst:

>>> print string.whitespace

Whitespace Zeichen bewegen den Cursor ohne etwas auszugeben. Sie erzeigen den "weißen Raum" zwischen den sichtbaren Zeichen (zumindest auf weißem Papier). Die Konstante string.whitespace enthält alle solchen nicht sichtbaren Zeichen, darunter das Leerzeichen, tab (\t), und newline (\n).

Es gibt noch eine Reihe weiterer nützlicher Funktionen im string Modul. aber dieses Buch soll ja kein Referenz-Handbuch sein, im Gegensatz zur Python Library Reference. Zusammen mit weiterer reichhaltiger Dokumentation ist es auf der Python Website verfügbar: www.python.org

7.11 Glossar

zusammengesetzter Datentyp
Ein Datentyp, bei dem die Werte aus Komponenten bestehen, also aus Elementen, die selbst Werte sind.
compound data type
A data type in which the values are made up of components, or elements, that are themselves values.
durchlaufen
Für alle Elemente einer Menge der Reihe nach eine ähnliche Operation ausführen.
traverse
To iterate through the elements of a set, performing a similar operation on each.
Index
Eine Variable oder ein Wert, der dazu benützt wird, ein Element einer geordneten Menge auszuwählen, z. B. ein Zeichen aus einem String
index
A variable or value used to select a member of an ordered set, such as a character from a string.
Abschnitt
Ein Teil eines Strings, der durch einen Breich von Indizes festgelegt wird.
slice
A part of a string specified by a range of indices.
veränderbar
Ein zusammengesetzter Datentyp, dessen Elementen neu Werte zugeordnet werden können.
mutable
A compound data types whose elements can be assigned new values.
Zähler
Eine Variable, die dazu benützt wird, etwas zu zählen. Normlalerweise wird sie mit Null initialisiert und dann inkrementiert.
counter
A variable used to count something, usually initialized to zero and then incremented.
inkrementieren
Den Wert einer Variablen um eins erhöhen.
increment
To increase the value of a variable by one.
dekrementieren
Den wert einer Variablen um eins verringern.
decrement
To decrease the value of a variable by one.
Whitespace-Zeichen
Alle Zeichen, die den Cursor bewegen, ohne sichtbare Zeichen auszugeben. Die Konstante string.whitespace enthält alle "whitespace" - Zeichen.
whitespace
Any of the characters that move the cursor without printing visible characters. The constant string.whitespace contains all the whitespace characters.


zurück rauf weiter Englisch Index