Erweiterte Schleifentechniken

dict.items()

Wie bereits in der vorangegangenen Einheit über Dictionaries vorgeführt, können sowohl die Schlüssel als auch die Werte gleichzeitig über die Methode items() angesprochen werden.

In [2]:
kernobst = ['Quitten', 'Äpfel', 'Birnen']
steinobst = ['Pflaumen', 'Kirschen', 'Aprikosen']
südfrüchte = ['Ananas', 'Bananen', 'Orange']
obst = {'kernobst': kernobst,
        'steinobst': steinobst,
        'südfrüchte': südfrüchte}

for k, v in obst.items():
     print(k.capitalize(),"sind", ",".join(v))
Kernobst sind Quitten,Äpfel,Birnen
Steinobst sind Pflaumen,Kirschen,Aprikosen
Südfrüchte sind Ananas,Bananen,Orange

enumerate()

Wenn über eine Sequenz (String, Liste) iteriert wird, dann kann der Index eines Elements und dessen Wert ebenfalls gleichzeitig über die Builtin-Funktion enumerate() angesprochen werden.

In [3]:
for i, v in enumerate(kernobst):
    print(i, v)
0 Quitten
1 Äpfel
2 Birnen
In [4]:
%%Mooc StringAssessment
Out[4]:

Enumerate

Es ist die folgende Liste von Steinobstsorten gegeben:


steinobst = ['Pflaumen', 'Kirschen', 'Aprikosen']

Sie sollen nun eine lesbare Aufzählung in einem Dokument oder einer Webseite daraus entwickeln, d.h. es soll die folgende textuelle Ausgabe (d.h. ein String) herauskommen:


1. Pflaumen
2. Kirschen
3. Aprikosen

Hinweis: Verwenden sie dabei sowohl die String-Methode join (es soll ein mehrzeiliger String entstehen) als auch die Funktion enumerate in einer entsprechenden List Comprehension! Bedenken sie zudem, dass enumerate ein Tupel aus einem Integer und dem eigentlichen Wert der Liste (hier also ein String) zurückgibt.

Beachte: Geben sie statt einem Zeilenumbruch '\n' in der Antwort ein '!N' ein - ansonsten wird die Überprüfung mittels des Check-Buttons nicht korrekt durchgeführt !

Geben sie das Ergebnis als Argument eines print()-Ausdrucks ein.



zip()

Um über mehrere Sequenzen zur gleichen Zeit zu iterieren, können die Elemente mit der zip()-Funktion zusammengefasst werden.

In [5]:
for so, ko, sf in zip(steinobst, kernobst, südfrüchte):
    print('Steinobst: {0} - Kernobst: {1} - Südfrüchte: {2}'.format(so, ko, sf))
Steinobst: Pflaumen - Kernobst: Quitten - Südfrüchte: Ananas
Steinobst: Kirschen - Kernobst: Äpfel - Südfrüchte: Bananen
Steinobst: Aprikosen - Kernobst: Birnen - Südfrüchte: Orange
In [6]:
Freunde = ['Wolfgang', 'Hans', 'Erich', 'Edith']
Telefonnr = ['0892345679', '015156784139', '082167868786', '080216787689']
print(dict(zip(Freunde,Telefonnr)))
{'Wolfgang': '0892345679', 'Hans': '015156784139', 'Erich': '082167868786', 'Edith': '080216787689'}
In [7]:
%%Mooc StringAssessment
Out[7]:

Zip um aus zwei Listen ein Dictionary zu erstellen

Es sind die folgenden beiden Listen gegeben:


Freunde = ['Wolfgang', 'Hans', 'Erich', 'Edith']
Telefonnr = ['0892345679', '015156784139', '082167868786', '080216787689']

Erstellen sie nun ein Dictionary mit den Schlüsselworten aus der Freundeliste (also den Vornamen) und den Werten aus der Telefonnr-Liste


Hinweis: Denken sie an die dict-Funktion.

Geben sie das Ergebnis als Argument eines print()-Ausdrucks ein.



reversed()

Um über eine Sequenz rückwärts zu iterieren kann die Builtin-Funktion reversed() verwendet werden.

In [8]:
print(steinobst)
for i in reversed(steinobst):
    print(i)
['Pflaumen', 'Kirschen', 'Aprikosen']
Aprikosen
Kirschen
Pflaumen

Um z.B. eine Liste dann wieder als neue Liste verwenden zu können, muss jedoch die Funktion list() noch vorgeschaltet werden.

In [9]:
neuerSteinObstKorb = list(reversed(steinobst))
print(steinobst)
print(neuerSteinObstKorb)
['Pflaumen', 'Kirschen', 'Aprikosen']
['Aprikosen', 'Kirschen', 'Pflaumen']

Zur Erinnerung: die List-Methode reverse() ändert die alte Liste direkt !

In [10]:
steinobst.reverse()
print(steinobst)
['Aprikosen', 'Kirschen', 'Pflaumen']

sorted()

Um über eine Sequenz sortiert zu iterieren kann die Builtin-Funktion sorted() verwendet werden, die eine neue sortierte Liste zurückliefert während die alte Liste unverändert bleibt - im Gegensatz zur List-Methode sort().

In [11]:
obstkorb = [y for x in obst.values() for y in x]
print(obstkorb)
sortierterObstkorb = sorted(obstkorb)
print(sortierterObstkorb)
['Quitten', 'Äpfel', 'Birnen', 'Aprikosen', 'Kirschen', 'Pflaumen', 'Ananas', 'Bananen', 'Orange']
['Ananas', 'Aprikosen', 'Bananen', 'Birnen', 'Kirschen', 'Orange', 'Pflaumen', 'Quitten', 'Äpfel']
In [12]:
print(obstkorb)
obstkorb.sort()
print(obstkorb)
['Quitten', 'Äpfel', 'Birnen', 'Aprikosen', 'Kirschen', 'Pflaumen', 'Ananas', 'Bananen', 'Orange']
['Ananas', 'Aprikosen', 'Bananen', 'Birnen', 'Kirschen', 'Orange', 'Pflaumen', 'Quitten', 'Äpfel']

Verändern von Listen in einer Schleife ist kritisch

Es ist manchmal verführerisch eine Liste zu verändern während über diese iteriert wird. Dies funktioniert oftmals auch, kann aber trotzdem in manchen Fällen kritisch werden.

In [13]:
import math
raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
for value in raw_data:
    if math.isnan(value):
        raw_data.remove(value)

print(raw_data)
[56.2, 51.7, 55.3, 52.5, 47.8]

Es ist daher oftmals einfacher und insbesondere sicherer stattdessen eine neuer Liste zu erzeugen und zu verwenden.

In [14]:
import math
raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
filtered_data = []
for value in raw_data:
    if not math.isnan(value):
        filtered_data.append(value)

print(filtered_data)
[56.2, 51.7, 55.3, 52.5, 47.8]
In [15]:
print()

In [16]:
print("\n".join(str(x) for x in enumerate(steinobst)))
(0, 'Aprikosen')
(1, 'Kirschen')
(2, 'Pflaumen')

Zusätzliche Informationen zu Bedingungen

Die Bedingungen, die in while- oder if-Ausdrücken verwendet werden, können beliebige Operatoren enthalten und nicht nur Vergleiche.

Die Vergleichsoperatoren in und not in überprüfen ob ein Element in einer Sequenz auftaucht oder eben nicht auftaucht. Die Operatoren is oder is not vergleichen ob zwei Objekte wirklich das gleiche Objekt sind, dies ist insbesondere für veränderliche Objekte wie Listen von Bedeutung. Alle Vergleichsoperatoren haben die gleiche Priorität, die kleiner ist als alle numerischen Operatoren.

Vergleiche können verkettet werden. Zum Beispiel wird mit dem Ausdruck a < b == c abgeprüft ob a kleiner als b ist und desweiteren ob b gleich c ist.

Vergleiche können mit den Bool'schen Operatoren and und or verknüpft werden und das Ergebnis dieses Vergleichs (oder jeder andere Bool'sche Ausdruck) kann zudem noch mit not negiert werden. Diese Operatoren haben eine kleinere Priorität als die Vergleichsoperatoren; unter ihnen hat not die höchste und or die geringste, sodass A and not B or C äquivalent zu (A and (not B)) or C ist. Wie üblich können Klammern dazu benutzt werden, alle möglichen Kompositionen darzustellen.

Die Bool'schen Operatoren and und or sind sogenannte Kurzschluss-Operatoren: ihre Argumente werden von links nach rechts ausgewertet und die Auswertung wird beendet sobald das Ergebnis bestimmt ist. Zum Beispiel, wenn A und C wahr sind und B falsch und der Ausdruck A and B and C ausgewertet werden soll, dann wird C nicht mehr ausgewertet. Der Rückgabewert einer Kurzschluss-Operation ist das letzte ausgewertete Argument.

Das Ergebnis eines Vergleichs oder eines anderen Bool'schen Ausdrucks kann natürlich auch als Variable abgespeichert werden:

In [17]:
text1, text2, text3 = '', 'Nördlingen', 'Memmingen'
nicht_null = text1 or text2 or text3
print(nicht_null)
Nördlingen

Zu Beachten ist, dass in Python eine Zuweisung nicht innerhalb eines Ausdrucks vorkommen darf. Dies verhindert, dass ein = in einem Ausdruck vorkommt obwohl ein == gemeint war.

Zusätzliche Informationen zu Vergleiche von Sequenzen und anderen Typen

Sequenz-Objekte können mit anderen Objekten desselben Sequenz-Typs verglichen werden. Bei dieser Art von Vergleichen wird die lexikografische Ordnung (angelehnt an die Ordnung der Wörter in einem Lexikon) benutzt. Zuerst werden die ersten beiden Elemente verglichen und sobald diese differieren beendet dies den Vergleich, falls diese gleich sind, werden die nächsten beiden Elemente verglichen und so weiter bis eine von beiden Sequenzen komplett durchlaufen wurde. Falls zwei zu vergleichende Elemente selbst Sequenzen desselben Typs sind wird der lexikografische Vergleich rekursiv weitergeführt. Falls alle Elemente der beiden Sequenzen gleich sind, werden die beiden Sequenzen als gleich betrachtet. Falls eine der Sequenzen eine Teilsequenz der anderen ist, ist die kürzere Sequenz die kleinere. Hier einige Beispiele von Vergleichen mit denselben Sequenz-Typen:

In [18]:
(1, 2, 3)              < (1, 2, 4)
Out[18]:
True
In [19]:
[1, 2, 3]              < [1, 2, 4]
Out[19]:
True
In [20]:
'ABC' < 'C' < 'Pascal' < 'Python'
Out[20]:
True
In [21]:
'ABC' < 'A'
Out[21]:
False
In [22]:
'C' < 'a'
Out[22]:
True
In [23]:
(1, 2, 3, 4)           < (1, 2, 4)
Out[23]:
True
In [24]:
(1, 2, 3)           < (1, 2, 4, 5)
Out[24]:
True
In [25]:
(1, 2)                 < (1, 2, -1)
Out[25]:
True
In [26]:
(1, 2, 3)             == (1.0, 2.0, 3.0)
Out[26]:
True
In [27]:
(1, 2, ('aa', 'ab'))   < (1, 2, ('abc', 'a'), 4)
Out[27]:
True

Zu beachten ist, dass Objekte unterschiedlicher Typen mit den Vergleichsoperatoren < oder > erlaubt, wenn es geeignete Vergleichsmethoden für diese Objekte gibt. Zum Beispiel können unterschiedliche numerische Typen verglichen werden wenn als Vergleich ihr numerischer Wert verwendet wird, z.B. 0 gleich ist mit 0.0, usw. Falls keine Vergleichsmethode vorhanden ist, wird eine Ausnahme mit einem TypeError geworfen.

In [28]:
%%Mooc Video
Out[28]:

Weitere Literatur

In [29]:
%%Mooc WebReference

Looping Techniques

https://docs.python.org/3/tutorial/datastructures.html#looping-techniques

Hinweis: Erweiterte Schleifentechniken

In [30]:
%%Mooc WebReference

More on Conditions

https://docs.python.org/3/tutorial/datastructures.html#more-on-conditions

Hinweis: Weitere Angaben zu Bedingungen

In [31]:
%%Mooc WebReference

Comparing Sequences and Other Types

https://docs.python.org/3/tutorial/datastructures.html#comparing-sequences-and-other-types

Hinweis: Vergleich von Sequenzen und anderen Typen

In [32]:
%%Mooc WebReference

Lexikografische Ordnung

https://de.wikipedia.org/wiki/Lexikographische_Ordnung

Hinweis: Genaueres zur lexikografischen Ordnung