Vorlesungsskript 13

Iteration mit for-Schleifen

Eine der größten Stärken von Computern ist es, dieselben Anweisungen beliebig oft zu wiederholen, jedes Mal auf ein neues Objekt angewendet. So muss der Programmierer die Anweisungen nur einmal schreiben, und der Computer wendet sie automatisch an – auf tausende von Zeilen in einer Textdatei, auf zehntausende Wörterbucheinträge oder auf Millionen von Online-Bestellungen, um nur ein paar Beispiele zu nennen.

Der Vorgang des Ausführens derselben Anweisungen für jedes Objekt in einer Sammlung von Objekten heißt Iteration (engl. iteration). In Python ist das wichtigste Werkzeug, um Iteration zu realisieren, die for-Schleife.

Die for-Schleife gehört zu den Blockanweisungen, d.h. es handelt sich um eine komplexe Anweisung, die sich über mehrere Zeilen erstrecken kann. Sie besteht aus einem Kopf und einem Körper. Der Körper besteht wiederum aus einer oder mehreren Anweisungen: Das sind die Anweisungen, die für jedes Element der Sammlung ausgeführt werden. Der Kopf der Schleife gibt zwei wichtige Dinge an: die Sammlung, über deren Elemente iteriert werden soll, und eine Variable, in der jedes Element zunächst abgelegt wird, bevor die Anweisungen für dieses Element ausgeführt werden.

Das war zum Beispiel die Schleife, mit der wir die Zeilen im Input gezählt haben:

for line in sys.stdin:
    line_count = line_count + 1

Die erste Zeile ist der Schleifenkopf. Er beginnt mit dem Schlüsselwort for. Es folgt ein frei zu wählender Variablenname, in diesem Fall line: Macht Sinn, denn wir iterieren über die Zeilen im Input. Jede Zeile wird somit von der Schleife automatisch in der Variablen line abgelegt, bevor weitere Anweisungen für diese Zeile ausgeführt werden. Es geht weiter mit dem Schlüsselwort in, dann kommt ein Ausdruck, der die Sammlung von Objekten angibt, über die wir iterieren. In diesem Fall ist das der Input des Programms, sys.stdin. Abgeschlossen wird der Schleifenkopf durch einen Doppelpunkt, dann geht es auf der nächsten Zeile weiter mit dem Schleifenkörper. Der wird dadurch vom Rest des Programms getrennt, dass er mit vier Leerzeichen eingerückt ist. In unserem Beispiel besteht der Schleifenkörper aus nur einer Anweisung und ist daher nur eine Zeile lang: Hier wird der Zeilenzähler jeweils um eins höher gesetzt.

Sammlungen (Iterables)

Grob gesagt lässt sich über alles iterieren, was mehrere Elemente enthält. Solche Objekte heißen Iterables und sind z.B.:

Beispiele

Zeilennummern

Dieses Programm (linenum.py) gibt den Input aus, aber mit der Zeilennummer vor jeder Zeile:

import sys

i = 0
for line in sys.stdin:
    i += 1
    print(i, line.rstrip())

Die eingebaute Funktion print gibt ihre Argumente aus, jeweils mit einem Leerzeichen dazwischen – und einem Newline-Zeichen am Ende. Deswegen benutzen wir hier die rstrip-Methode, um die bereits vorhandenen Newline-Zeichen am Ende abzuschneiden. Sonst würden wir nach jeder Zeile noch eine leere Zeile kriegen.

Ein Beispiel-Aufruf:

$ cat moby-dick.txt | python3 linenum.py | tail -n 20
23846 lives!'"
23847   --WHARTON THE WHALE KILLER.
23848 
23849     "So be cheery, my lads, let your hearts never fail,
23850     While the bold harpooneer is striking the whale!"
     23851   --NANTUCKET SONG.
23852 
23853     "Oh, the rare old Whale, mid storm and gale
23854       In his ocean home will be
23855     A giant in might, where might is right,
23856       And King of the boundless sea."
23857   --WHALE SONG.
23858 
23859 
23860 
23861 
23862 
23863 End of The Project Gutenberg Etext of Moby Dick, by Herman Melville
23864 
23865

99 Bottles of Beer

Dieses Programm gibt den Liedtext von 99 Bottles of Beer aus:

for i in range(99, 2, -1):
    print(i, 'bottles of beer on the wall', i, 'bottles of beer.')
    print('Take one down and pass it around,', i - 1, 'bottles of beer on the wall.')
    print()
print('2 bottles of beer on the wall, 2 bottles of beer.')
print('Take one down and pass it around, 1 bottle of beer on the wall.')
print()
print('1 bottle of beer on the wall, 1 bottle of beer.')
print('Take one down and pass it around, no more bottles of beer on the wall.')
print()
print('No more bottles of beer on the wall, no more bottles of beer.')
print('Go to the store and buy some more, 99 bottles of beer on the wall.')

Die range-Funktion wird hier mit drei Argumenten aufgerufen. Für range(i, j) beginnt die Folge mit i und endet direkt vor j. Das dritte Argument ist die Schrittlänge. Soll abwärts gezählt werden wie hier, muss diese negativ sein.

Ruft man die print-Funktion ohne Argument auf, gibt sie nur ein Newline-Zeichen aus.

Sortieren

Dieses Programm sortiert die Zeilen im Input (fast wie sort):

import sys

lines = []
for line in sys.stdin:
    lines.append(line.rstrip())
lines.sort()
for line in lines:
    print(line)