For-Schleifen
Einführung
Wie auch die while-Schleife ist die for-Schleife eine Kontrollstruktur, mit der eine Gruppe von Anweisungen (ein Block) wiederholt ausführt werden kann. Die Syntax der For-Schleifen unterscheiden sich in den verschiedenen Programmiersprachen. Ebenso ist die Semantik einer For-Schleife, also wie sie vom Compiler oder Interpreter zu verstehen bzw. auszuführen ist, von Programmiersprache zu Programmiersprache unterschiedlich. Die "klassische" numerische Schleife, wie sie C und C++ kennt, besitzt eine Schleifenvariable, die mit einem Startwert initialisiert wird und nach jedem Durchlauf des Schleifenkörpers verändert wird, d.h. meistens um einen bestimmten Wert (z.B. 1) erhöht oder vermindert wird, bis der definierte Zielwert erreicht ist. Man nennt diese Schleifenform auch Zählschleife, weil die Schleifenvariable und damit auch der Startwert, der Endwert und die Schrittweite numerisch sein müssen. Im Beispiel sehen wir eine for-Schleife in C, die die Zahlen von 1 bis 100 ausdruckt:
for( i = 1; i <= 100; i++)
printf("i: %d\n", i);
Auch wenn Sie diese Schleifenform bereits in C oder einer anderen Sprache liebgewonnen haben, müssen wir Sie leider enttäuschen: Python kennt keine solche for-Schleife. Wohlgemerkt "keine solche" aber sehr wohl eine for-Schleife. Die in Python benutzte Art von For-Schleife entspricht der in der Bash-Shell oder in Perl verwendeten foreach-Schleife. Bei dieser Schleifenart handelt es sich um ein Sprachkonstrukt mit dessen Hilfe nacheinander die Elemente einer Menge oder Liste bearbeitet werden können. Dazu werden sie einer Variable zugewiesen.
Syntax der For-Schleife in Python
Im folgenden sehen wir die allgemeine Syntax der for-Schleife in Python. Sequenz steht für ein iterierbares Objekt, also beispielsweise eine Liste, ein Tupel oder ein Dictionary.
for Variable in Sequenz: Anweisung_1 Anweisung_2 ... Anweisung_n else: Else-Anweisung_1 Else-Anweisung_2 ... Else-Anweisung_m
Wie bereits gesagt, dient in Python die For-Schleife zur Iteration über ein Sequenz von Objekten, während sie in vielen anderen Sprachen meist nur "eine etwas andere while-Schleife" ist.
Beispiel einer for-Schleife in Python:
languages = ["C", "C++", "Perl", "Python"]
for language in languages:
print(language)
Der optionale else-Block ist etwas Besonderes in Python. Während Perl-Programmierern dieses Konstrukt vertraut ist, ist es für C und C++-Programmierer ein ungewöhnliches Konzept. Semantisch funktioniert der optionale else-Block der for-Anweisung wie der else-Block der while-Anweisung. Er wird nur ausgeführt, wenn die Schleife nicht durch eine break-Anweisung abgebrochen wurde. Das bedeutet, dass der else-Block nur dann ausgeführt wird, wenn alle Elemente der Sequenz abgearbeitet worden sind.
Trifft der Programmablauf auf eine break-Anweisung, so wird die Schleife sofort verlassen und das Programm wird mit der Anweisung fortgesetzt, die der for-Schleife folgt, falls es überhaupt noch Anweisungen nach der for-Schleife gibt.
Üblicherweise befindet sich die break-Anweisung innerhalb einer Konditionalanweisung, wie im folgenden Beispiel:
edibles = ["ham", "spam","eggs","nuts"]
for food in edibles:
if food == "spam":
print("No more spam please!")
break
print("Great, delicious " + food)
else:
print("I am so glad: No spam!")
print("Finally, I finished stuffing myself")
edibles = ["ham","eggs","nuts"]
for food in edibles:
if food == "spam":
print("No more spam please!")
break
print("Great, delicious " + food)
else:
print("I am so glad: No spam!")
print("Finally, I finished stuffing myself")
Vielleicht ist unsere Abscheu vor dem Dosenfutter "spam" nicht so groß, dass wir sofort aufhören zu essen. In diesem Fall kommt die continue-Anweisung ins Spiel. In dem folgenden kleinen Skript benutzen wir continue, um mit dem nächsten Artikel der essbaren Artikel weiterzumachen. "continue" schützt uns davor, "spam" essen zu müssen:
edibles = ["ham", "spam", "eggs","nuts"]
spam = False
for food in edibles:
if food == "spam":
print("No more spam please!")
spam = True
continue
print("Great, delicious " + food)
# here can be the code for enjoying our food :-)
else:
if spam:
print("I didn't like the spam!")
else:
print("I am so glad: No spam!")
print("Finally, I finished stuffing myself")
Die range()-Funktion
In Python gibt es eine einfache Möglichkeit Zählschleifen zu simulieren. Dazu benötigt man die range()-Funktion. range() liefert einen Iterator, der Zahlen in einem bestimmten Bereich (range) bei Bedarf, - also beispielsweise in einer For-Schleife, - liefern kann. Bevor wie die allgemeine Syntax angeben, zeigen wir die einfachste Benutzung von range() in einem Beispiel:
range(10)
list(range(10))
Obiges Beispiel zeigt, dass range(), wenn man es mit einem einzelnen Argument aufruft, einen Iterator liefert, der die Zahlen von 0 (inklusive) bis zu diesem Wert (exklusive) generieren kann. Um eine entsprechende Liste aus dem Iterator zu erzeugen, benutzt man den cast-Operator list(). range() kann aber auch mit zwei Argumenten aufgerufen werden:
range(begin, end)Dann wird ein Iterator für alle ganzen Zahlen von begin (einschließlich) bis end (ausschließlich) geliefert. Beispiel:
range(4, 10)
list(range(4, 10))
Mit einem optionalen dritten Argument kann man range() noch die Schrittweite mitgeben, wie wir im folgenden Beispiel sehen:
list(range(4, 50, 5))
Das ganze geht natürlich auch rückwärts:
list(range(42, -12, -7))
Besonders sinnvoll wird die range()-Funktion im Zusammenspiel mit der for-Schleife. Im nachfolgenden Beispiel bilden wir die Summe der Zahlen von 1 bis 100:
n = 100
s = 0
for counter in range(1, n+1):
s += counter
print("Sum of 1 until " + str(n) + ": " + str(s) )
Dies lässt sich nun ganz einfach im Zusammenspiel mit range und der eingebauten Funktion "sum" bewerkstelligen. Mit "sum" kann man die Elemente numerischer Listen oder Tupel addieren, d.h. Listen oder Tupel, die nur numerische Werte enthalten. die Summe der Zahlen von 1 bis n lässt sich also ganz einfach wie folgt berechnen:
sum(range(101))
Beispiel: Berechnung der pythagoräischen Zahlen
Beweis des Satzes von Pythagoras Die meisten glauben, dass der Satz von Pythagoras von Pythagoras entdeckt worden war. Warum sonst sollte der Satz seinen Namen erhalten haben. Aber es gibt eine Debatte, ob dieser Satz nicht auch unabhängig von Pythagoras und vor allen Dingen bereits früher entdeckt worden sein könnte. Für die Pythagoräer - eine mystische Bewegung, die sich auf die Mathematik, Religion und die Philosophie begründete - waren die ganzen Zahlen, die den Satz des Pythagoras erfüllten, besondere Zahlen, die für sie heilig waren.
Heutzutage haben die Pythagoräischen Zahlen nichts mystisches mehr. Obwohl sie für manche Schülerin oder Schüler oder andere Personen, die mit der Mathematik auf Kriegsfuß stehen, immer noch so erscheinen mögen.
Ganz unromantisch gilt in der Mathematik: Drei natürliche Zahlen, welche die Gleichung
a2+b2=c2erfüllen, heißen pythagoräische Zahlen.
Das folgende Programm berechnet alle pythagoräischen Zahlen bis zu einer einzugebenden maximalen Zahl:
from math import sqrt
n = int(input("Maximale Zahl? "))
for a in range(1,n+1):
for b in range(a,n):
c_square = a**2 + b**2
c = int(sqrt(c_square))
if ((c_square - c**2) == 0):
print(a, b, c)
Iteration über eine Liste mit range()
Falls man auf die Indexe einer Liste zugreifen möchte, scheint es keine gute Idee zu sein eine For-Schleife zur Iteration über die Liste zu nutzen. Man kann dann zwar alle Elemente erreichen, aber der Index eines Elementes ist nicht verfügbar. Aber es gibt eine Möglichkeit sowohl auf den Index als auch auf das Element zugreifen zu können. Die Lösung besteht darin range() in Kombination mit der len()-Funktion, die einem die Anzahl der Listenelemente liefert, zu benutzen:
fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21]
for i in range(len(fibonacci)):
print(i,fibonacci[i])
print()
colours = ["red"]
for i in colours:
if i == "red":
colours += ["black"]
if i == "black":
colours += ["white"]
print(colours)
Am besten benutzt man eine Kopie der Liste, wie im nächsten Beispiel:
colours = ["red"]
for i in colours[:]:
if i == "red":
colours += ["black"]
if i == "black":
colours += ["white"]
print(colours)
Auch jetzt haben wir die Liste verändert, aber "bewusst" innerhalb des Schleifenkörpers. Aber die Elemente, die über die For-Schleife iteriert werden, bleiben unverändert durch die Iterationen.