Kapitel 6: Anweisungen

Werbung
Kapitel 6: Anweisungen
Grundlagen der Programmierung 1
Holger Karl
Wintersemester 2016/2017
Inhaltsverzeichnis
Inhaltsverzeichnis
1
Abbildungsverzeichnis
2
Liste von Definitionen u.ä.
6.1
Überblick . . . . . . . . .
6.2
Programm . . . . . . . .
6.3
Bedingte Ausführung: if
6.4
Schleifen: while . . . . .
6.5
Schleifen: for . . . . . .
6.6
List comprehensions . .
6.7
Geschachtelte Schleifen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
3
3
4
12
22
32
34
6.8
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . 41
Abbildungsverzeichnis
6.1
6.2
6.3
Flussdiagramm einer einfachen While-Schleife . . . . . . . . .
goto considered harmful . . . . . . . . . . . . . . . . . . . . . .
Flussdiagramm einer While-Schleife mit continue , break und
else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zuweisung an Aufzählung während while-Schleife . . . . . . .
Zwischenstand bei einer Iteration über ein Dict D.items() . .
Selection Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.4
6.5
6.6
13
21
23
25
29
38
Liste von Definitionen u.ä.
6.1
6.2
6.3
6.1
6.2
6.4
6.3
6.5
6.6
Definition (pass) . . . . . . . . . . . . . .
Definition (Anweisung: if/elif/else)
Definition (Block) . . . . . . . . . . . . .
Achtung (Nicht pythonisch) . . . . . . . .
Achtung (Bedingung genau beachten) . .
Definition (while) . . . . . . . . . . . . .
Achtung (Keine korrekte Schleife!) . . . .
Definition (for-Schleife) . . . . . . . . .
Definition (Hilfsfunktion: range) . . . .
2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
12
12
15
19
22
23
24
29
6.1. Überblick
6.1
6.1.1
Überblick
Was bisher geschah
• Wir können bis jetzt
– Werte aufschreiben, was Objekte erzeugt
– aus Objekten Ausdrücke für neue Objekte bilden
* mit Aufruf von Funktionen als Beispiel
– mit Namen auf Objekte referenzieren (zuweisen)
* mit der Definition einer Funktion als Sonderfall
• Also: Folgen von Zuweisungen
– Die eine nach der anderen ausgeführt werden
Aber: Kein Einfluss auf Reihenfolge der Ausführung!
6.1.2
Dieses Kapitel
• Wir nehmen Einfluss auf die Reihenfolge der Ausführung von Anweisungen
• Dazu brauchen wir weitere Anweisungen
– Bedingungen, Schleifen
• Wir verallgemeinern die Vorstellung, was eine Anweisung ist
6.2
6.2.1
Programm
Ein Programm
• Ein Programm ist eine Folge von Anweisungen
– Ausgeführt entsprechend des Ausführungsmodells
– Bis jetzt: Sequentiell, Funktionsaufruf
• Um die Reihenfolge der Anweisungen zu beeinflussen, müssen wir das
Ausführungsmodell erweitern
6.2.2
Anweisungen – bis jetzt
• Die Zuweisung =
• Die Funktionsdefinition def
• Die Rückkehr aus einer Funktion return
Und die Folge von Anweisungen
3
4
Liste von Definitionen u.ä.
• Erinnerung: Eine Zeile, eine Anweisung!
6.2.3
Bedingte Folge von Anweisungen
Idee:
• Programms nicht immer bei der nächsten Anweisung fortsetzen
• Sondern die Wahl der nächsten auszuführenden Anweisung von dem
Wert eines Ausdrucks abhängig machen
• Alternativen im Programm vorsehen
6.2.4
Schleifen von Anweisungen
Idee:
• In der Fortsetzung des Programms erlauben, zu vorherigen Anweisungen
zurückzukehren
• Meist (nicht unbedingt) abhängig vom Wert eines Ausdrucks
• Wiederholungen oder Schleifen erlauben
6.3
6.3.1
Bedingte Ausführung: if
Neue Anweisung: if
• Die Anweisung if besteht aus zwei Teilen:
– Einem Ausdruck, der auf wahr oder falsch ausgewertet wird
– Eine Folge von Anweisungen – der so genannte block
• Semantik: die angegebene Folge von Anweisungen nur ausführen, wenn
der Ausdruck zum Zeitpunkt der Ausführung den Wert wahr hat
– Auswertung des Ausdrucks einmal vor Ausführung des Blocks
6.3.2
1
2
3
4
if: Syntax
if Ausdruck:
Anweisung1
Anweisung2
usw.
5
6
7
# if hier zu Ende
Anweisung nach if
6.3. Bedingte Ausführung: if
Beobachtung
• Das Ende des Ausdrucks wird durch Doppelpunkt : markiert
• Die durch if kontrollierten Anweisungen werden unterhalb von if eingerückt aufgeschrieben
• Der Block endet dort, wo die Einrückung endet
6.3.3
if: Syntax im Vergleich mit def
• Syntax ist der von def sehr ähnlich
– Schlüsselwort, dann ein Ausdruck, dann ein Doppelpunkt
– Dann eingerückt die kontrollierten Anweisungen
– Ende der Einrückung = Ende des Blocks (if, def, etc.)
• Typisches Muster der Syntax von Python!
6.3.4
Warum Einrückung?
• Einrückung ist kompakt, leicht lesbar
• Erzwingt ordentliche Struktur des Codes
– Keine Variationsmöglichkeiten wie in anderen Sprachen
• Readability counts (PEP 20)
Vergleich mit anderen Sprachen
Wenn Sie andere Sprachen wie C oder Java kennen, wird Ihnen die Kompaktheit
dieser Formulierung auffallen. Keine runden Klammern um den Ausdruck
erforderlich, keine geschweiften Klammen, um den Beginn und das Ende der
kontrollierten Anweisungen zu kontrollieren. Kein überflüssiges Wort then,
was in manchen Sprachen vorkommt. Insgesamt ist die Syntax von Python
sehr knapp und frugal.
6.3.5
Alternative: Wahr oder falsch?
• Erweiterung: Zwei Code-Blöcke, für den Wahr- und den Falsch-Fall
1
2
3
4
5
6
7
8
9
if Ausdruck:
# Block für wahr:
Anweisung1
Anweisung2
...
else:
# Block für falsch:
Anweisung1
Anweisung2
5
6
Liste von Definitionen u.ä.
...
10
11
12
13
14
# Anweisungen nach if/else
Anweisung1
...
Achtung
Doppelpunkt nach else!
6.3.6
Alternative: Semantik
• Der Ausdruck wird einmal ausgewertet und auf wahr oder falsch überprüft
• Danach wird entweder der Wahr-Block oder der Falsch-Block ausgeführt
6.3.7
1
2
if: Beispiele
if True:
print("Ja!")
Ja!
1
2
3
4
if not True:
print("Ja!")
else:
print("Nein!")
Nein!
6.3.8
if: Beispiel Betrag
Wie Code ergänzen, um den Betrag einer Zahl zu bestimmen?
1
2
3
4
5
6
def betrag(x):
"""Liefere Absolutbetrag von x"""
if (???):
return ???
else:
return ???
6.3. Bedingte Ausführung: if
7
8
9
6.3.9
print("Betrag von 5: ", betrag(5))
print("Betrag von -3: ", betrag(-3))
Ausflug: Code testen
Wie sind Sie sicher, dass Ihre Lösung stimmt?
• Erste Idee: Testfälle ausprobieren
• Von Hand? Automatisch!
• Insbesondere: Randfälle
Aber: sicher? Nein. . .
6.3.10
Test-Anweisung: assert
assert: Anweisung, der ein Ausdruck folgt
• Wenn Ausdruck wahr, weitermachen
• Wenn Ausdruck falsch, mit Fehler abbrechen
1
2
3
4
5
def betrag(x):
if (x>0):
return x
else:
return -1 * x
6
7
8
9
10
6.3.11
assert
assert
assert
assert
5 == betrag(5)
7 == betrag(-7)
0 == betrag(0)
"abc" == betrag("abc")
Tests für quersumme3
Was wären gute assert-Anweisungen für die Funktion quersumme3 aus
vorherigem Kapitel?
1
2
def quersumme3(t):
return t[0] + t[1] + t[2]
3
4
5
# Nuetzliche asserts?
assert True
7
8
Liste von Definitionen u.ä.
6.3.12
Geschachtelte if/else
Beobachtung:
• if/else ist eine Anweisung
• Im Block von if bzw. else dürfen Anweisungen stehen
Darf dann da auch ein if/else stehen ?
• Die Logik der Syntax gibt das her
• Also: JA!
6.3.13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
6.3.14
Geschachtelte if/else: Allgemeiner Fall
if Bedingung1:
Teilblock1
if Bedingung2:
Teilblock2
else:
Teilblock3
# Ende des inneren if
Teilblock4
else:
Teilblock5
if Bedingung3:
Teilblock6
else:
Teilblock7
# Ende des zweiten inneren if
Teilblock8
# Ende von if
Geschachtelte if/else: Einfachere Fälle
• Die ganzen Teilblöcke dürfen auch leer sein
• Leerer Teilblock nach else?
– Dann kann man das else auch weglassen und nur das if schreiben
6.3.15
Leerer Teilblock nach if?
Würde das gehen?
6.3. Bedingte Ausführung: if
1
2
3
if Bedingung:
else:
Anweisung
Kein leerer Block nach if!
Nein, nach if muss Anweisung folgen!
• Aber wenn da nichts zu tun ist?
– Weil Code noch kommt, . . . ?
• Sonderanweisung: pass
6.3.16 pass: Beispiel
Angenommen, Sie wollen Wert der Variable laenge auf mindestens 100 aber
höchstens 200 eingrenzen:
1
2
3
4
5
6
7
8
9
laenge = 252
if laenge >= 100:
if laenge <= 200:
pass
else:
laenge = 200
else:
laenge = 100
print(laenge)
200
6.3.17
Anweisung: pass
Definition 6.1 (pass). pass ist die leere Anweisung: Sie verändert den
Zustand des Programms nicht und geht zur folgenden Anweisung über.
pass wird typischerweise benutzt
• wo die Syntax eine Anweisung vorschreibt aber keine sinnvolle Handlung
möglich ist oder
• als ein Platzhalter für noch zu ergänzenden Code.
6.3.18
Eindeutigkeit von else?
Ist immer eindeutig klar, zu welchem if ein else gehört?
9
10
Liste von Definitionen u.ä.
Beispiel 1
1
2
3
4
5
if Bedingung1:
if Bedingung 2:
Block1
else:
Block2
Beispiel 2
1
2
3
4
5
if Bedingung1:
if Bedingung 2:
Block1
else:
Block2
Unproblematisch
Dank Einrückung ist die Syntax eindeutig
Verschachtelte if/else in anderen Sprachen
Auch hier wieder: in anderen Sprachen werden die Blöcke häufig durch Konstrukte wie geschweifte Klammern markiert. Das ist zwar semantisch ebenfalls
eindeutig, für einen Menschen aber ggf. viel schwerer zu lesen und verwirrend,
wenn die optische Einrückung nicht mit der Klammerstruktur übereinstimmt.
Wir werden uns im Java-Teil der Vorlesung hier noch einige unschöne Beispiele
anschauen.
6.3.19
Häufiger Fall: Nach else wieder ein if
• Szenario: Wenn nicht das, ist dann das der Fall? Und wenn das nicht, dann
das? . . . ?
• Mit if/else ausdrückbar, aber schrecklich lesbar
1
2
3
4
5
6
7
if Bedingung1:
Anweisung1
else:
if Bedingung2:
Anweisung2
else:
if Bedingung3:
6.3. Bedingte Ausführung: if
8
9
10
6.3.20
Anweisung3
else:
Anweisung4
Allgemeine Form: if/elif/else
Gleicher Effekt, aber knapper: elif
1
2
3
4
5
6
7
8
if Bedingung1:
Anweisung1
elif Bedingung2:
Anweisung2
elif Bedingung3:
Anweisung3
else:
Anweisung4
Doppelpunkt
Auf Doppelpunkt nach elif-Bedingung achten!
6.3.21 if/elif/else: Beispiel
1
2
3
4
5
6
7
8
9
L = [1, 2, 17, 42]
if len(L) < 3:
print("zu kurz")
elif len(L) > 5:
print("zu lang")
elif len(L) == 4:
print("ausgereizt")
else:
print("knapp")
ausgereizt
11
12
Liste von Definitionen u.ä.
6.3.22
Definition: if/elif/else
Definition
6.2
(Anweisung: if/elif/else). Die Anweisung
if/elif/else ermöglichen die alternative Ausführung einer Folge
von Anweisungen – eines Blocks – in Abhängigkeit des Wahrheitswertes eines
Ausdrucks (if) bzw. mehrerer Ausrücke (if und folgende elif Ausdrücke).
Dem if kann optional ein oder mehrere elif und optional höchstens ein
else-Teil folgen.
Die Blöcke werden durch Einrückung den jeweiligen Bedingungen bzw.
dem else zugeordnet.
Definition: Block
Definition 6.3 (Block). Ein Block ist eine Folge beliebiger Anweisungen
(mindestens eine Anweisung). Die Zustandsänderung, die ein Block bewirkt,
ist die Zustandsänderung, die sich durch die sequentielle Ausführung der Anweisungen des Blocks ergibt. Sequentiell bezieht sich hier auf die Reihenfolge
der Anweisung im Programmcode.
6.4
6.4.1
Schleifen: while
Allgemeine Schleifen
• Idee: Wiederhole einen Block solange, wie eine Bedingung wahr ist
• Typisch: Anweisungen im Block werden Einfluss auf den Test haben
• Grundform:
1
2
6.4.2
while Test
Block
while: Flussdiagramm
Abbildung 6.1 zeigt eine erste Vorstellung einer while-Schleife in Python als
Flussdiagramm.
6.4.3
while: Beispiel Zählschleife
6.4. Schleifen: while
Abbildung 6.1: Flussdiagramm einer einfachen While-Schleife
1
2
3
4
5
6.4.4
a=0
b=5
while a < b:
print(a, end=" ")
a += 1
Beobachtung: Sichtbarkeit von Variablen
• Vorheriges Beispiel: Auf Variable a wurde innerhalb der Schleife zugegriffen
• Offenbar unproblematisch
• Regel: Schon vor der Schleife bekannte Variablen bleiben innerhalb des
Blocks sichtbar
– Sie sind im gleichen Scope (und auch im gleichen Namensraum)
6.4.5
Beobachtung: Sichtbarkeit von Variablen (2)
• Was ist umgekehrt? Variable wird erst in Schleife erzeugt?
1
2
3
i = 0
while i < 2:
i += 1
13
14
Liste von Definitionen u.ä.
4
5
x = 2*i
print(x)
4
Variable nach Schleife sichtbar
• Variable bleibt nach der Schleife erhalten und zeigt auf entsprechenden
Wert
6.4.6
Schleifen: Terminierung
Gefahr: Schleifenbedingung stets wahr
• Schleife wird nicht verlassen
• Programm in Endlosschleife
6.4.7
Einfache Regeln für Terminierung
Schleife terminiert bestimmt, wenn es
• eine Variable gibt, die in jedem Schleifendurchlauf streng monoton wächst
und
• die Variable diskret wächst und
• die Schleifenbedingung eine obere Schranke darstellt
Analog: Variable schrumpft, untere Schranke
6.4.8
Terminierung ist kritisch!
Q. How did the programmer die in the shower?
A. He read the shampoo bottle instructions: Lather. Rinse. Repeat.
6.4.9
Beispiel: GGT
Bestimme den größten gemeinsamen Teiler
1
2
3
4
5
6
7
a = 18
b = 12
while (a != b):
if a>b:
a = a-b
else:
b = b-a
6.4. Schleifen: while
Terminiert für alle Eingaben?
6.4.10 while: Schleife über Feld
Beispiel: Werte in einer Liste aufaddieren
1
2
3
4
5
6
7
L = [1, 2, 3, 4]
i = 0
sum = 0
while i < len(L):
sum = sum + L[i]
i = i + 1
print(sum)
10
Achtung 6.1 (Nicht pythonisch). Das ist nicht Python-Style (pythonic). Hier
nur als didaktischer Zwischenschritt!
6.4.11 while: Beispiel Suchschleife
Szenario:
• Wir haben eine Liste (oder Tuple)
• Wir suchen ein Element mit einer bestimmten Eigenschaft
– Allgemeiner als mit index machbar: da nur Identität als Eigenschaft möglich
Idee:
• Mit einer Schleife die Elemente ablaufen
• Testen, ob Eigenschaft erfüllt
– Merken, dass gefunden
6.4.12 while: Beispiel Suchschleife (2)
1
2
3
4
5
6
7
# ist eine ungerade Zahl in L?
def ungerade_in_liste(L):
gefunden = False
i = 0
while i < len(L):
if L[i] % 2 == 1:
gefunden = True
15
16
Liste von Definitionen u.ä.
8
9
i = i + 1
return gefunden
10
11
12
print(ungerade_in_liste([2, 18, 6, 5, 9]))
print(ungerade_in_liste([2, 18, 6, 10, 22]))
True
False
Beobachtung
• Alle Elemente untersuchen?
– Nein, nach erstem Finden aufhören?
6.4.13 while: Beispiel Suchschleife (3)
Zusätzliches Abbruchkriterium: not gefunden
1
2
3
4
5
6
7
8
9
# ist eine ungerade Zahl in L?
def ungerade_in_liste(L):
gefunden = False
i = 0
while (not gefunden) and (i < len(L)):
if L[i] % 2 == 1:
gefunden = True
i = i + 1
return gefunden
10
11
12
print(ungerade_in_liste([2, 18, 6, 5, 9]))
print(ungerade_in_liste([2, 18, 6, 10, 22]))
True
False
6.4.14
Schleifenbedingungen finden?
Inspiration? Oder strukturiertes Vorgehen?
• Idee: Nach der Schleife soll irgendeine Zielbedingung gelten
• Während der Schleife gilt die Schleifenbedingung
• Schön wäre: Negation der Schleifenbedingung ist Zielbedingung?
– Oder: impliziert Zielbedingung?
6.4. Schleifen: while
1
2
while SCHLEIFENBEDINGUNG == True:
...
3
4
6.4.15
# Es gilt: ZIELBEDINGUNG == True
Schleifenbedingungen finden? (2)
Oft praktisch: Schleifenbedingung konstruieren aus zwei Teilen
• Die Zielbedingung an sich: Was wollen wir nach der Schleife erreicht
haben?
– Oder eine stärkere Variante davon
• Eine Invariante: Gilt vor, während, nach der Schleife
– Stellt sicher, dass alle Anweisungen innerhalb der Anweisung korrekt ausgeführt werden können
– Beispiel: Index für Listenzugriffe gültig
Schleifenbedingung zusammensetzen
Schleifenbedingung = (not Zielbedingung) and Invariante
• Invariante kann oft entfallen, aber hilfreich zum Nachdenken
6.4.16
Schleifenbedingung finden? (3)
Mit Schleifenbedingung = (not Zielbedingung) and Invariante
nach Schleife gilt:
Zielbedingung or (not Invariante)
Was gilt also?
D.h.: Nach Schleife nicht klar, was eigentlich der Fall ist!?
• Es könnte die Zielbedingung gelten
• Es könnte aber auch die Invariante verletzt sein
Also unklar!
6.4.17
Nach Schleife: Prüfen!
Wenn also unklar ist, weswegen die Schleife beendet wurde
• also wegen Erreichen der Zielbedingung
• oder Verletzten der Invariante
Dann muss man ggf. nach der Schleife nachprüfen!
• Häufiges Muster: Zielbedingung durch Variable explizit darstellen
17
18
Liste von Definitionen u.ä.
• Wie im Beispiel oben: gefunden
6.4.18
1
2
3
Beispiel umformuliert
# ist eine ungerade Zahl in L?
def ungerade_in_liste(L):
i = 0
4
5
6
ZIELBEDINGUNG = False
INVARIANTE = i < len(L)
7
8
9
10
11
while (not ZIELBEDINGUNG) and INVARIANTE:
ZIELBEDINGUNG = (L[i] % 2 == 1)
i = i + 1
INVARIANTE = i < len(L)
12
13
return ZIELBEDINGUNG
14
15
16
print(ungerade_in_liste([2, 18, 6, 5, 9]))
print(ungerade_in_liste([2, 18, 6, 10, 22]))
True
False
6.4.19
Schleifen: Hilfskonstrukte
Innerhalb einer Schleife kann viel passieren
• Wirklich jede Iteration komplett durchlaufen?
• Eine Schleife abbrechen?
6.4.20
Schleifeniterationen nicht komplett durchlaufen
Typisches Muster: Umständlich
1
2
3
4
5
6
7
while Schleifenbedingung:
Anweisungen
if Andere_Bedingung:
# Lasse den Rest der Schleife aus
pass
else:
Restliche Anweisungen
6.4. Schleifen: while
6.4.21
Schleifeniterationen nicht komplett durchlaufen: continue
Gleich, aber knapper:
1
2
3
4
5
6.4.22
while Schleifenbedingung:
Anweisungen
if Andere_Bedingung:
continue
Restliche Anweisungen
Schleife abbrechen
Typisches Muster: Umständlich
1
2
3
4
5
6
6.4.23
while (not Abbruchsbedingung) and WeitereBedingung:
Anweisungen
if Abbruchsbedingung:
pass
else:
Restliche Anweisungen
Schleife abbrechen: break
Gleich, aber knapper:
1
2
3
4
5
while WeitereBedingung:
Anweisungen
if Abbruchsbedingung:
break
Restliche Anweisungen
Achtung 6.2 (Bedingung genau beachten). Vorsicht, das Weglassen der Abbruchsbedingung aus der Schleifenbedingung im Einzelfall genau überlegen.
6.4.24
Reguläre Beendigung vs. break: Reaktion
Unterschiedliches Beenden einer Schleife kann unterschiedliche Reaktionen
erfordern – siehe oben
Unterstützung: else für Schleife!
19
20
Liste von Definitionen u.ä.
6.4.25 else bei Schleifen
Beispiel:
1
2
3
4
5
6
7
8
9
10
def is_prime(n):
"""Ist n eine Primzahl?"""
x = n // 2
while x > 1:
if n % x == 0:
print(n, ’hat Teiler’, x)
break
x -= 1
else:
print(n, ’ist eine Primzahl’)
# For some n > 1
# Remainder
# Skip else
# Normal exit
11
12
13
14
15
print("Ist 5 eine Primzahl?")
is_prime(5)
print("Ist 9 eine Primzahl?")
is_prime(9)
6.4.26 else bei Schleifen (2)
• Vorteil: Keine Test-Variable nötig
– Vereinfacht Schleifenbedingung
– Vereinfacht Anweisungen in der Schleife
– Wohldefinierte Art, Anweisungen für einen typischen Fall zu platzieren – leichte Lesbarkeit durch Konvention
6.4.27 while: Suchschleife mit else
1
2
3
4
5
6
7
8
9
10
# ist eine ungerade Zahl in L?
def ungerade_in_liste(L):
i = 0
while (i < len(L)):
if L[i] % 2 == 1:
break
i = i + 1
else:
print("nix ungerades!")
return False
11
12
13
return True
6.4. Schleifen: while
14
15
print(ungerade_in_liste([2, 18, 6, 5, 9]))
print(ungerade_in_liste([2, 18, 6, 10, 22]))
True
nix ungerades!
False
while und else: Sinnvoll?
In den hier gezeigten, kleinen Beispielen ist der Einsatz von else möglicherweise nicht vollständig überzeugend. Der Nutzen wird wirklich klar, wenn
im else-Teil einer Schleife nicht-triviale Operationen durchlaufen werden
müssen, zum Beispiel eine Fehlerbehandlung, weitere Verarbeitungsschritte,
etc. Wir kommen in den Übungsaufgaben darauf zurück.
6.4.28
Stil: continue, break ?
Ist das überhaupt guter Stil? Wird das Programm unstrukturiert?
• Das ist beinahe Glaubenssache
• Aber break und continue haben klar definiertes Verhalten
• Insbesondere in Verbindung mit else alle Fälle eines Schleifenendes
im Programmcode klar identifizierbar
Also: Ja, das ist ok! Mit Verständnis!
6.4.29
Stil: goto
• In alten Sprachen (und in Maschinensprache): goto
– Springe an beliebige Stelle im Programm
• Aber: Goto considered harmful
Abbildung 6.2: goto considered harmful
21
22
Liste von Definitionen u.ä.
6.4.30
Definition: while
Definition 6.4 (while). Eine while-Schleife besteht aus einem Ausdruck
als Test (Schleifenbedingung) und einem Rumpf (Schleifenrumpf, Schleifenkörper). Beim Einreichen der while-Anweisung wird der Test-Ausdruck ausgewertet und mit dem booleschen Wert True verglichen. Ist der Test-Ausdruck
wahr, wird der Rumpf einmal ausgeführt. Das Testen des Ausdrucks und eine
Ausführung des Rumpfes werden als (Schleifen-)Iteration bezeichnet. Die Veränderungen des Zustands durch die Anweisungen des Rumpfs sind (natürlich)
wirksam.
Danach wird wie beim Erreichen der while-Anweisung verfahren: Der
Test wird (mit den neuen Variablen-Werten) ausgewertet und ggf. der Rumpf
ausgeführt.
Der Rest einer Schleifeniteration kann durch die Anweisung continue
übersprungen werden und mit der folgenden Iteration begonnen werden. Eine
Schleife kann mit der Anweisung break abgebrochen werden.
Am Ende einer regulär (nicht durch break) beendeten Schleife wird ein
ggf. vorhandener Block nach der Anweisung else ausgeführt. Bei Beendung
der Schleife durch break wird dieser Block ignoriert.
6.4.31 while: Komplettes Flussdiagramm
Abbildung 6.3 zeigt ein vollständiges Flussdiagramm einer while-Schleife in
Python.
6.5
6.5.1
Schleifen: for
Häufiger Fall: Schleife über Aufzählung
Häufig: Eine Aufzählung (Liste, Tuple, usw) Element für Element verarbeiten
Skizze:
1
2
3
4
5
6
7
L = [1, 2, 3, 4, 5]
while L is not []:
aktuellesElement = L[0]
# mache etwas mit aktuellem Element
# ...
# betrachte die restlichte Liste:
L = L[1:]
6.5. Schleifen: for
Abbildung 6.3: Flussdiagramm einer While-Schleife mit continue , break und
else
Achtung 6.3 (Keine korrekte Schleife!). Dies ist keine korrekte Schleife; sie
hat mindestens zwei Probleme. Siehe Details in der Übungsaufgabe.
6.5.2
Häufige Fälle verdienen eigene Anweisung: for
Schleifen über Aufzählungen vereinfacht schreiben
1
2
3
4
5
6
# Sei A eine Referenz auf
# ein Objekt eines Aufzählungsdatentyp
for element in A:
Anweisung1
Anweisung2
...
7
8
9
# Beispiel:
L = [1, 2, 3]
23
24
Liste von Definitionen u.ä.
10
11
6.5.3
for l in L:
print(l, end=" ")
for: Definition
Definition 6.5 (for-Schleife).
• Mit jeder Iteration einer for Schleife
wird das jeweils nächste Element der gegeben Aufzählung der Schleifenvariable (auch Laufvariable) zugewiesen (im Beispiel: element; Name
ist frei wählbar)
• Nach Bearbeitung des letzten Elements der Aufzählung wird die Schleife
verlassen
• Ist die Aufzählung leer (z.B. []), so wird die Schleife nicht betreten und
keine Iteration ausgeführt
• Die Anweisungen break, continue und else verhalten sich genau
wie bei while-Schleifen
6.5.4
Zuweisung an Aufzählung?
Was passiert, wenn der Aufzählung einer neuer Wert zugewiesen wird?
• Ändert das den Schleifenverlauf?
• Beispiel:
1
2
3
4
6.5.5
L = [1, 2, 3]
for l in L:
print(l, end=" ")
L = [17, 18, 19]
Zuweisung an Aufzählung – es passiert gar nicht!
• Tatsächlich kann an die Aufzählung, die für die Schleife verwendet wird,
gar nicht zugewiesen werden
• Zu Beginn der for-Schleife wird eine weitere, verborgene Variable für
die Aufzählung angelegt
– Anhand dieser wird iteriert
• Weißt man also einer Variable, die im Schleifenkopf benutzt wird, einen
neuen Wert zu, so beeinflusst das nicht den Schleifenablauf
– Der ursprüngliche Wert steht ja weiterhin zur Verfügung
Visualisierung
Die Visualisierung dieses Effekts durch unsere üblichen Diagramme gelingt
leider nicht gut (Abbildung 6.4). Der verborgene Name für die Aufzählung
6.5. Schleifen: for
wird durch Pythontutor leider nicht explizit dargestellt. Dennoch hilft dieses
Diagramm vielleicht ein wenig.
Abbildung 6.4: Zuweisung an Aufzählung während while-Schleife
6.5.6
Zuweisung an Elemente der Aufzählung?
Was passiert also hier?
1
2
3
4
6.5.7
L = [1, 2, 3]
for l in L:
print(l, end=" ")
L[1] = 17
Zuweisung an Schleifenvariable
Was passiert, wenn der Schleifenvariable etwas zugewiesen wird?
• Ändert das die Aufzählung? Den Schleifenverlauf?
• Beispiel:
1
2
3
4
L = [1, 2, 3, 4, 5]
for x in L:
x += 1
print(L)
[1, 2, 3, 4, 5]
25
26
Liste von Definitionen u.ä.
Nein!
Auch hier ist die ursprüngliche Aufzählung nicht betroffen
• Die Schleifenvariable x ist ein Name für den Wert; zeigt nicht in die
Aufzählungsstruktur
• x wird bei erneutem Betreten der Schleife einfach den nächsten Wert
aus der Aufzählung zugewiesen
6.5.8
Schleifenvariable nach Schleifenende?
Bleibt Schleifenvariable erhalten nach Schleifenende?
1
2
3
for i in [1, 2, 3]:
print("in schleife")
print("Variable i nach Schleife: ", i)
in schleife
in schleife
in schleife
(’Variable i nach Schleife: ’, 3)
Ja
• Mit Wert des letzten Durchlaufs
6.5.9
for-Schleifen über andere Aufzählungen
• Beispiele bisher: for über Liste
• Laut Kapitel 5: Andere Aufzählungen sind str, tuple, set
– Und eigentlich auch dict
• for-Schleifen darüber?
6.5.10 for-Schleifen über andere Aufzählungen – Beispiele
1
2
3
1
2
3
s = "Hallo GP1"
for ss in s:
print(ss, end=" ")
t = (1, 2, 3, 4)
for tt in t:
print(tt, end=" ")
6.5. Schleifen: for
6.5.11 for-Schleifen über andere Aufzählungen – Beispiele
• Überraschend? Nein!
– Principle of least surprise
1
2
3
s = {1, 2, 3, 4, 2, 3, 4}
for ss in s:
print(ss, end=" ")
• Überraschend? Nein!
– Semantik einer Menge
6.5.12 for-Schleife über verschachtelte Datentypen
Beispiel: Liste von Tupeln
1
2
3
L = [ (1,2), (3, 4), (5, 6)]
for t in L:
print(t, end=" ")
6.5.13 for-Schleife mit erweiterter Zuweisung?
• Eigentlich macht ja eine for-Schleife jeweils eine Zuweisung an die
Laufvariable
• Python kennt erweiterte Zuweisungen und unpacking: x, y = (1,
2)
• Funktioniert das bei for?
1
2
3
4
L = [ (1,2), (3, 4), (5, 6)]
for a, b in L:
print(a, b)
print("---")
(1, 2)
--(3, 4)
--(5, 6)
---
27
28
Liste von Definitionen u.ä.
6.5.14 for-Schleife über dict ?
• Iterieren über ein dict liefert die Schlüssel
1
2
3
D = {"a": 1, "b": 2, "c": 3, "d": "abc"}
for key in D:
print(key, end=" ")
6.5.15 for-Schleife über dict – Key und Value?
Wir bekommen eine Liste von Schlüssel-/Wert-Tuple eines dicts mit Aufruf
von items
• Mit implizitem unpacking der Tuple in separate Variablen k (für key)
und v (für value)
1
2
3
4
D = {"a": 1, "b": 2, "c": 3, "d": "abc"}
for k, v in D.items():
print(k, v)
print("----")
(’a’,
---(’c’,
---(’b’,
---(’d’,
----
1)
3)
2)
’abc’)
Beobachtung: Reihenfolge
• Es gibt keine Garantie für die Reihenfolge in D.items()!
Visualisierung
Zur Illustration (Abbildung 6.5) hier ein Schnappschuss aus dem zweiten
Durchlauf der Schleife. Die beiden Schleifenvariablen key und value referenzieren dabei Werte aus dem Dictionary D.
6.5.16 for über Folge von Zahlen: range
• Häufig: Liste über eine Folge Zahlen
6.5. Schleifen: for
Abbildung 6.5: Zwischenstand bei einer Iteration über ein Dict D.items()
– Z.B. 1 . . . 10, 1 . . . n für Variable n, usw
• Mit for so nicht unmittelbar darstellbar
– Mit while schon, aber umständlich
Definition 6.6 (Hilfsfunktion: range). range(stop) liefert eine Aufzählung der Zahlen von 0 bis (ausschliesslich) stop
6.5.17 range: Beispiel
1
2
for i in range(11):
print(i, end=" ")
6.5.18 range: Wie viele Durchläufe?
Fencepost-Problem: Wie viele Pfähle braucht man für einen 100m langen
Zaun mit Pfählen im Abstand von 10m?
• 9, 10, 11?
6.5.19
Terminierung von for und range
Terminiert das hier?
29
30
Liste von Definitionen u.ä.
1
2
for i in range(5):
i -= 1
Terminierung von range
Natürlich terminiert das. Der Schleifenstruktur ist egal, was innerhalb der
Schleife mit dem Namen i gemacht wird (genauer: auf welchen Wert der
Name i referenziert). Am Ende der Schleife wird der nächste Wert aus der
Aufzählung verwendet.
6.5.20 range: Aufzählung verändern
Erinnerung: Das hier verändert die Aufzählung L nicht
1
2
3
4
L = [1, 2, 3, 4, 5]
for x in L:
x += 1
print(L)
[1, 2, 3, 4, 5]
L verändern?
Was aber, wenn Schleife doch L verändern soll?
6.5.21 range: Aufzählung verändern
Dann brauchen wir eine for-Schleife mit Zugriff auf L durch den Index
1
2
3
4
L = [1, 2, 3, 4, 5]
for i in range(len(L)):
L[i] += 1
print(L)
[2, 3, 4, 5, 6]
Muster
Typisches Muster für den Einsatz von range und len in for-Schleifen
• Durch Struktur der for-Schleife Indiz an Leser des Codes!
6.5. Schleifen: for
6.5.22
31
Aufzählung in for – duck typing?
Im Kopf der for-Schleife:
• Muss es eine Aufzählung sein?
• Oder – nach duck typing-Prinzip – reicht etwas, dass sich wie eine
Aufzählung benimmt?
– Dafür haben wir noch kein Beispiel – aber vielleicht ein interessanter Gedanke!
6.5.23
Beispiel: Sieb des Erathostenes
• Bestimme alle Primzahlen bis zu einer gegebenen Obergrenze n
• Idee:
– Schreibe alle Zahlen von 2 bis n
– Nimm die erste Zahl (die 2); streiche alle Vielfachen dieser Zahl
aus der Tabelle
– Nimm die nächste noch nicht gestrichene Zahl und wiederhole
Prozedur
– Bis keine nicht gestrichene Zahl mehr übrig
6.5.24
Eratostenes: Umsetzung
• Wie Tabelle repräsentieren?
– Als Liste der Zahlen: [2, 3, 4, 5, ... ]
* Möglich, aber dann Suche nach Vielfachen aufwändig
– Als Liste von gestrichen/nicht gestrichen Werte, mit Zugriff per
Index
* nicht/gestrichen als True oder False repräsentieren
6.5.25
1
2
3
4
5
6
7
8
Erathostenes: Code
n = 20
prim = [True] * n
for i in range(n):
if i==0 or i==1:
prim[i] = False
elif prim[i] == True:
for streich in range(2*i, n, i):
prim[streich] = False
9
10
print(prim)
[False, False, True, True, False, True, False, True, False, False, False, True
32
Liste von Definitionen u.ä.
range mit drei Parametern
Parameter: Start, Stop, Schrittweite!
6.5.26 while oder for ?
• Ist eine Aufzählung abzuarbeiten; ist eine feste Anzahl an Durchläufen
bekannt? Dann for
• Ist nur eine Abbruchbedingung bekannt, bei unklarer Anzahl an Durchläufen? Dann while
6.6
6.6.1
List comprehensions
Listen in Schleife konstruieren
• Häufiges Muster:
– Eine Schleife produziert Ergebnis pro Druchlauf
– Ergebnisse werden in Liste aufgesammelt
• Einfachster Fall: Einen Ausdruck für jedes Element der Aufzählung berechnen
1
2
3
4
6.6.2
# leere Liste zum Ergebnisse sammeln:
ergebnis = []
for x in aufzaehlung:
ergebnis.append(Ausdruck ueber x)
Listen in Schleife konstruieren – Beispiel
Beispiel: Wir verdoppeln jeden Eintrag der Liste
1
2
3
4
ergebnis = []
for x in [1, 2, 3, "abc", "xyz"]:
ergebnis.append(x * 2)
print(ergebnis)
[2, 4, 6, ’abcabc’, ’xyzxyz’]
6.6. List comprehensions
6.6.3
Listen in Schleifen bedingt konstruieren
• Auch häufig: Pro Durchlauf Ergbnis nur bei bestimmer Bedingung konstruieren
1
2
3
4
5
6.6.4
# leere Liste zum Ergebnisse sammeln:
ergebnis = []
for x in aufzaehlung:
if x erfuellt Bedingung:
ergebnis.append(Ausdruck ueber x)
Listen in Schleifen bedingt konstruieren – Beispiel
Verdopple Eintrag nur wenn gerade Zahl:
1
2
3
4
5
ergebnis = []
for x in [1, 2, 3, 17, 42, 99]:
if x % 2 == 0:
ergebnis.append(x * 2)
print(ergebnis)
[4, 84]
6.6.5
List comprehensions
Wie üblich: Häufige Muster verdienen eigene Syntax!
List comprehension:
• Konstruieren einer Liste aus einer anderen Liste
• mit einer kompakten for-Formulierung
1
[Ausdruck ueber x
for x in Liste if x erfuellt Bedingung]
Schleifenvariable
Natürlich auch andere Variablennamen als x möglich
6.6.6
List comprehension – Beispiel 1
Verdopple Eintrag nur wenn gerade Zahl:
33
34
Liste von Definitionen u.ä.
1
2
3
4
5
6.6.7
# Zeilenumbruch nur für Lesbarkeit
ergebnis = [x * 2
for x in [1, 2, 3, 17, 42, 99]
if x % 2 == 0]
print(ergebnis)
Beispiel 2
• Liste der Noten von Austauschstudierenden
1
2
3
4
5
6
7
# Liste mit Matrikelnummern:
austausch = [11, 22, 33]
# Dict mit Matrikelnummer: Note Abbildung
noten = {11: 2.0, 17: 1.7, 20: 3.3, 22: 1.0, 27: 5.0, 33: 2.3}
# Liste der Noten der Austauschstudierenden:
austauschnoten = [noten[a] for a in austausch]
print(austauschnoten)
[2.0, 1.0, 2.3]
Fehler?
Was passiert, wenn Matrikelnummer fehlt?
6.7
6.7.1
Geschachtelte Schleifen
Geschachtelte Schleifen
•
•
•
•
6.7.2
Schleifenrumpf: Folge von Anweisungen
Schleifen (while und for) sind Anweisungen
Also: Schleifen in Schleifen möglich!?
Na klar!
Paarweise Operation
• Angenommen, wir wollen Elemente zweier Listen paarweise miteinander
vergleichen
– Schleife 1 (äußere Schleife): Iteriere über eine Liste
6.7. Geschachtelte Schleifen
35
– Schleife 2 (innere Schleife): In jeder Iteration der äußeren Schleife,
iteriere über die zweite Schleife
* Führe Operation durch
1
2
3
6.7.3
for l1 in liste1:
for l2 in liste2:
operation auf l1, l2
Paarweise Operation: Beispiel 1 – Summe der Produkte
Berechne Summe der Produkte jedes Elements von Liste 1 mit jedem Element
von Liste 2
Plen(L )−1 Plen(L2 )−1
• Also: i=0 1
L1 [i]L2 [j]
j=0
1
2
3
4
5
6
7
L1 = [1, 2, 3]
L2 = [17, 18, 19]
summe = 0
for l1 in L1:
for l2 in L2:
summe += l1 * l2
print(summe)
324
6.7.4
Paarweise Operation: Beispiel 2 – Test auf enthalten
Welche Elemente von tests sind in der Liste items?
• Innere Schleife abbrechen wenn Ergebnis feststeht
1
2
items = ["aaa", 111, (4, 5), 2.01]
tests = [(4, 5), 3.14]
# Eine Liste von Daten
# Wonach suchen wir?
3
4
5
6
7
8
9
10
11
for key in tests:
# Fuer alle zu suchenden Daten
for item in items:
# Fuer alle vorhandenen Daten
if item == key:
# Gleich?
print(key, "gefunden in Daten")
break
# Brich die innere Schleife ab
else:
print(key, "nicht in Daten")
# Nur ausgefuehrt wenn innere Schleife
# nichts gefunden hat
36
Liste von Definitionen u.ä.
((4, 5), ’gefunden in Daten’)
(3.14, ’nicht in Daten’)
6.7.5
Beispiel mit geschachteltem range
Berechne
1
2
3
4
5
P10 Pi
i=0
j=0 i
·j
summe = 0
for i in range(11):
for j in range(i+1):
summe += i*j
print(summe)
1705
6.7.6
Beispiel mit geschachteltem range und list comprehension
List comprehensions erlauben direkt geschachtelte Schleifen:
1
2
3
4
5
6
7
6.7.7
quadrate = [i*j
# aeußere Schleife:
for i in range(11)
# innere Schleife:
for j in range(i+1)
]
print(quadrate)
Eingebaute Funktion: sum
Hilfsfunktion sum: Addiere alle Elemente einer Aufzählung auf
1
2
3
4
5
6
7
summe = sum([i*j
# aeußere Schleife:
for i in range(11)
# innere Schleife:
for j in range(i+1)
])
print(summe)
6.7. Geschachtelte Schleifen
6.7.8
Beispiel: Sortieren
• Gegeben: Eine Liste mit Zahlen
• Gesucht: Eine Liste mit den gleichen Zahlen, aber aufsteigend sortiert
Idee: Suche die kleinste Zahl aus Restliste
• Schritt 1: Suche die kleinste Zahl aus der ganzen Liste
– Vertausche mit Element am Anfang
• Schritt 2: Genauso, mit der Liste ab Position 2
• Usw.
Selection Sort
Sog. Selection Sort
• Achtung: Für Praxis ungeeignet; viel zu langsam; aber schön einfach
• Besser: siehe VL Datenstrukturen und Algorithmen
6.7.9
Selection Sort: Vorüberlegung
• Wie viele, welche Schleifen?
– Eine Schleife, um das erste, zweite, . . . Element zu bestimmen: for
– Um ein Element zu bestimmen, den Rest absuchen: noch eine for,
geschachtelt
6.7.10
1
2
3
4
5
6
7
Selection Sort: Code
liste = [17, 1, 42, 99, 33]
for pos in range(len(liste)):
tausch = pos
for such in range(pos+1, len(liste)):
if liste[such] < liste[tausch]:
tausch = such
liste[pos], liste[tausch] = liste[tausch], liste[pos]
8
9
print(liste)
[1, 17, 33, 42, 99]
(PT link)
37
38
Liste von Definitionen u.ä.
Visualisierung
Abbildung 6.6 visualisiert einen Zwischenstand beim Ablauf von Selection
Sort.
Abbildung 6.6: Selection Sort
6.7.11
Sortieren in Python: Eingebaut
• Niemand schreibt so eine Sortier-Funktion von Hand
• Das ist als eingebaute Funktion verfügbar: l.sort() für eine Liste l
6.7.12
Beispiel: Mischen zweier Listen
• Gegeben: Zwei sortierte Listen (beliebiger Länge)
• Gesucht: Eine sortierte Liste, die die Elemente der beiden Listen enthält
6.7.13
Mischen: Vorüberlegung
• Triviale Idee: Listen hintereinander kopieren, dann sortieren
– Verschwenderisch – wir können die Sortierung der Listen ja ausnutzen
• Bessere Idee: Gehe Listen elementweise durch und nimm jeweils das
kleinere Element
6.7.14
1
2
3
Mischen konventionell
a = [1, 3, 6, 9, 12, 23, 27, 35]
b = [2, 4, 5, 10, 11, 17, 18]
r = []
4
5
aindex = 0
6.7. Geschachtelte Schleifen
6
bindex = 0
7
8
9
10
11
12
13
14
15
while (aindex < len(a)) and (bindex < len(b)):
print("Index a und b:", aindex, bindex)
if a[aindex] < b[bindex]:
r.append(a[aindex])
aindex += 1
else:
r.append(b[bindex])
bindex += 1
16
17
print("Index a und b nach Schleife:", aindex, bindex)
18
19
20
21
22
if aindex == len(a):
r.extend(b[bindex:])
else:
r.extend(a[aindex:])
23
24
print("Resultat: ", r)
(’Index a und b:’, 0, 0)
(’Index a und b:’, 1, 0)
(’Index a und b:’, 1, 1)
(’Index a und b:’, 2, 1)
(’Index a und b:’, 2, 2)
(’Index a und b:’, 2, 3)
(’Index a und b:’, 3, 3)
(’Index a und b:’, 4, 3)
(’Index a und b:’, 4, 4)
(’Index a und b:’, 4, 5)
(’Index a und b:’, 5, 5)
(’Index a und b:’, 5, 6)
(’Index a und b nach Schleife:’, 5, 7)
(’Resultat: ’, [1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 17, 18, 23, 27, 35])
6.7.15
1
2
3
4
5
6
Mischen mit Slicing
a = [1, 3, 6, 9, 12, 23]
b = [2, 4, 5, 10, 11, 17, 18]
r = []
while (len(a) > 0) and (len(b) > 0):
print(a, b)
if a[0] < b[0]:
39
40
Liste von Definitionen u.ä.
7
8
9
10
11
r.append(a[0])
a = a[1:]
else:
r.append(b[0])
b = b[1:]
12
13
14
15
16
if len(a) == 0:
r.extend(b)
else:
r.extend(a)
17
18
print("Resultat: ", r)
([1, 3, 6, 9, 12, 23], [2, 4, 5, 10, 11, 17, 18])
([3, 6, 9, 12, 23], [2, 4, 5, 10, 11, 17, 18])
([3, 6, 9, 12, 23], [4, 5, 10, 11, 17, 18])
([6, 9, 12, 23], [4, 5, 10, 11, 17, 18])
([6, 9, 12, 23], [5, 10, 11, 17, 18])
([6, 9, 12, 23], [10, 11, 17, 18])
([9, 12, 23], [10, 11, 17, 18])
([12, 23], [10, 11, 17, 18])
([12, 23], [11, 17, 18])
([12, 23], [17, 18])
([23], [17, 18])
([23], [18])
(’Resultat: ’, [1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 17, 18, 23])
6.7.16
Beispiel: Binäre Suche
• Gegeben:
– Sortierte Liste mit Werten
– Gesuchter Wert
• Gesucht:
– Index des Wertes in Liste, falls vorhanden
– Information dass nicht vorhanden, andernfalls
6.7.17
Binäre Suche, Vorüberlegung
• Liste linear absuchen?
– Funktioniert, aber wir können Sortierung ausnutzen!
• Idee:
– Prüfe Wert in der Mitte der Liste
* Falls gefunden: fertig
* Wenn größer: Suche oben; wenn kleiner: suche unten
6.8. Zusammenfassung
– Wenn kein Wert mehr übrig, fertig
• Welche Schleifen?
6.7.18
1
2
3
4
5
Binäre Suche, Code
l = [2, 4, 5, 10, 11, 17, 18]
wert = 11
gefunden = False
unten = 0
oben = len(l)
6
7
8
9
10
11
12
13
14
15
16
while ((not gefunden) and
(unten <= oben) and
(unten < len(l))):
mitte = int((unten+oben)/2)
if l[mitte] == wert:
gefunden = True
elif l[mitte] < wert:
unten = mitte + 1
else:
oben = mitte -1
17
18
print(gefunden, mitte)
(True, 4)
Frage
Wozu braucht man die Schleifenbedingung unten < len(l) ?
6.8
Zusammenfassung
6.8.1
Zusammenfassung
• Wiederholte Ausführung von Anweisungen ist extrem nützlich
• Unterschiedliche Kontrollmechanismen existieren
– while-Schleife: Kontrolle durch einen Ausdruck, der Wahrheitswert liefert
41
42
Liste von Definitionen u.ä.
– for-Schleife: In jeder Wiederholung nimmt eine (oder mehrere)
Schleifenvariable einen Wert aus einer vorgegebenen Aufzählung
an
• Schleifen erlauben Ausnahmen (break, continue) und Code für reguläres Ende (else)
• Zusammen mit ein paar Hilfsfunktionen (vor allem range) sind insbes.
for-Schleifen in Python extrem praktisch
6.8.2
Python-Keywords: Liste bis jetzt
• Bis jetzt:
– True, False, and, or, def, return, None
– in
• Neu:
– if, else, pass, elif, while, for, break, continue, assert
6.8.3
Python: eingebaute Funktionen
• Allgemein
– print, range, zip
• Typ-bezogen
– len
• Datentypen erzeugen
– tuple
– list
– set
– dict
Herunterladen