16. Der Prozentoperator für Strings

Stellt euch vor, ihr müsstet eine Funktion schreiben, die folgendes tut:

>>> formatWithDigits(78)
'78 hat 2 Ziffern'
>>> formatWithDigits(4893)
'4893 hat 4 Ziffern'
>>> formatWithDigits(5)
'5 hat 1 Ziffer'

Die Funktion soll also einen String zurückgeben (und nicht ausgeben – wenn euch der Unterschied noch nicht klar ist, seht euch nochmal die Kapitel über Funktionen an), in dem das Argument in einer Art Schablone gemeinsam mit irgendwelchen Eigenschaften des Arguments steht. Auch wenn dieses Beispiel etwas bemüht wirken mag, tauchen derartige Aufgaben in der Praxis sehr häufig auf.

Wir könnten das Problem so lösen:

def formatWithDigits(anInt):
  return anInt+" hat "+len(str(anInt))+" Ziffern"

Das ist allerdings langsam und außerdem recht aufwändig. Abgesehen davon haben wir natürlich das Problem einstelliger Zahlen nicht gelöst (was bei negativen Zahlen passieren soll, ist dann noch eine andere Frage).

Eine Lösung mit dem Prozentoperator sieht so aus:

def formatWithDigits(anInt):
  return "%d hat %d Ziffern"%(anInt,
    len(str(anInt)))

An diesem einfachen Beispiel mag der wahre Nutzen noch nicht ganz erkennbar sein, aber diese Art, Strings zu bauen, ist praktisch immer dem Zusammenkonkatenieren vorzuziehen.

Der Prozentoperator verknüpft einen String, der als Schablone (template) dient, mit einem Tupel. In der Schablone sind durch %? Felder markiert, in die der Reihe nach die Werte aus dem Tupel eingetragen werden. Statt des ? steht in Wirklichkeit ein Formatcode, der bestimmt, wie der Wert dargestellt wird. Verbreitet sind s (String), d (Integer), f, g und e (Float) sowie % (ein Prozentzeichen).

Zwischen Prozent und Formatcode können noch diverse Optionen kommen, etwa Längen.

>>> "|%5d|%05d|%-5d|"%(2,2,2)
'|    2|00002|2    |'
>>> "|%1f|%3.9e|%+1.2g|"%(1.23,1.23,1.23)
'|1.230000|1.230000000e+00|+1.2|'

Die Details über all das stehen im Kapitel String Formatting Operations der Python-Referenz – seht euch diese Seite jetzt an. Ihr müsst nicht auswendig wissen, wie was genau geht, aber ihr solltet wissen, was es alles gibt.

Was ihr mitnehmen solltet: Normalerweise sagt eine Zahl zwischen % und Formatcode etwas über die Breite des Feldes aus, und ein - vor der Zahl macht etwas links- statt rechtsbündig, was für Strings und Ints ziemlich analog läuft. Für Fließkommazahlen muss es natürlich ein paar mehr Merkmale geben.

Der Längencode darf auch ein Stern sein, dann wird die Länge aus einem weiteren Formatargument gelesen:

>>> for l in range(1,6):
...     print "%*d"%(l, l)
...
1
 2
  3
   4
    5

Übungen zu diesem Abschnitt

Ihr solltet euch wenigstens an den rötlich unterlegten Aufgaben versuchen

(1)

Der Prozentoperator ist euer Freund, er macht das Zusammenbauen von Strings in genau der beabsichtigten Weise zu einer wahren Freude (im Zweifel in Verbindung mit list comprehensions – die uns später begegnen werden – und der join-Methode von Strings). Überlegt euch für die folgenden Fragen jeweils einen Formatstring und probiert aus, ob auch das rauskommt, was rauskommen soll.

  1. Ihr habt eine ganze Zahl i und einen String s. Ihr möchtet das im Format s: i haben, wobei s linksbündig in einem 30 Zeichen breiten Feld und i rechtsbündig in einem 5 Zeichen breiten Feld stehen soll.
  2. Dito, nur soll s diesmal rechtsbündig sein
  3. Dito, nur soll i diesmal mit führenden Nullen ausgegeben werden
  4. Dito, nur soll i jetzt eine Fließkommazahl sein und mit zwei Vorkommastellen und drei Nachkommastellen ausgegeben werden (probiert aus, was passiert, wenn die Zahlen zu groß für das Feld werden)

(2)

Verbessert unsere formatWithDigits-Funktion, so dass sie auch einstellige und negative Zahlen korrekt behandelt.

Vielleicht wollt ihr auch mal sehen, wie ihr das Problem mit string.join löst.


Markus Demleitner

Copyright Notice