Python Datencontainer

Willemers Informatik-Ecke


Bestellen bei Amazon
2015-07-31

Diese Seiten sind Grundlage meines Python-Buchs aus den ersten Recherchen.

Python stellt für die Kombination von Daten einige Container zur Verfügung. Sie ermöglichen die Kombination von Daten in Listen, aber auch in assoziativen Datenstrukturen, bei denen die Daten über einen Schlüssel ermittelt werden.

Sequenz

Eine Sequenz ist eine Kombination von Elementen gleichen Typs, die über rechteckige Klammern ausgelesen werden können. Eine Sequenz ist immutable, als unveränderlich. Es können also nach der Erzeugung keine einzelnen Elemente mehr geändert werden.

Mit der Zeichenkette - auch String genannt - kennen wir bereits die wichtigste Sequenz.

Die Erläuterungen für den Umgang mit den rechteckigen Klammern finden Sie bei den Zeichenketten.

Tupel

Ein Tupel besteht aus mehreren Werten. Ein Tupel ist wie eine Sequenz immutable, als unveränderlich. Ein Tupel wird also bei seiner Erzeugung mit Werten belegt und kann danach nicht mehr geändert werden. Im Gegensatz zur Sequenz kann ein Tupel unterschiedliche Typen nebeneinander enthalten.

Sie können ein Tupel definieren, indem sie der Variablen eine kommaseparierte Folge von Werten zuweisen. Beispielsweise könnten Sie das Datum 31.8.1996 als Tupel definieren:

datum = 31, 8, 1996
Üblicherweise werden die Werte in Klammern gesetzt. Damit wird schon optisch deutlicher, dass die Werte zusammengehören.
datum = (31, 8, 1996)
Aber auch bei der Übergabe eines Tupels als Parameter an eine Funktion wird dieses in Extraklammern gesetzt, um deutlich zu machen, dass es sich um ein Tupel und nicht um eine Folge von Einzelwerten handelt.
machwasdamit(31, 8, 1996)
machwasdamit((31, 8, 1996))
In der ersten Form werden drei ganzzahlige Werte an drei Parameter übergeben, in der zweiten Form wird ein dreiteiliges Tupel an einen Parameter übergeben.

Parameter und Rückgabewerte von Funktionen

Die einzelnen Werte des Datums können nach Ihrer Erzeugung nicht mehr verändert werden. Wenn Sie also den 31.8.1997 ansprechen wollten, müssten Sie ein komplett neues Datum anlegen.

Eine Funktion kann auch ein Tupel zurückgeben. Dazu reicht es, die Werte kommagetrennt zurückzugeben.

def machwasdamit(datum):
    return 28,12,1998

neudatum = machwasdamit((31,8,1996))
tag, monat, jahr = neudatum
print(tag, monat, jahr, neudatum)
Wies Sie sehen, können Sie die Bestandteile des Datums auch wieder zerlegen, indem Sie links neben das Gleichheitszeichen drei Variablen setzen. Je eine für den Tag, den Monat und das Jahr. Es müssen aber genau so viele Variablen sein, wie Elemente in dem Tupel existieren, sonst hustet Ihnen der Interpreter einen ValueError vor.

Gemischtwaren

Tupel müssen nicht nur aus Zahlen bestehen. Es dürfen gern auch andere Typen sein. Sie dürfen sie sogar mischen.
meinErstesAuto = ("Renault", "R4", 34, 125)
Hier ist die Reihenfolge der Werte als Marke, Typ, Leistung in PS und Geschwindigkeit in km/h angenommen.

Wollen Sie allerdings ein Auto modellieren wollen, sollten Sie vielleicht doch besser eine Klasse verwenden.

Auf die Elemente eines Tupels können Sie mit rechteckigen Klammern zugreifen, wie es im Zusammenhang mit den Zeichenketten beschrieben ist.

Sie können Tupel miteinander vergleichen. Dabei werden die einzelnen Elemente nacheinander verglichen. Sobald ein Vergleichspaar nicht mehr gleich ist, wird daran festgemacht, welches kleiner ist.

altdatum = (31,8,1996)
neudatum = (28,12,1998)
print(altdatum < neudatum)
Hier ergibt sich der Wert False, weil 31 nicht kleiner als 28 ist. Auf diese Weise wird auch Gleichheit und Ungleichheit verglichen.

Liste

Listen fassen mehrere einzelne Werte, die durchaus unterschiedlichen Typs sein können, zu einer Variablen zusammen. Die einzelnen Elemente einer Liste sind im Gegensatz zu einem Tupel nachträglich änderbar.

Jede einzelne Zahl kann separat erstellt und verändert werden. Das Beispiel zeigt eine Liste der Lottozahlen. Bei der Definition werden die Elemente in rechteckige Klammern gesetzt. Ein sehr einfaches Beispiel sind die Lottozahlen. Im folgenden Beispiel werden sie definiert und dann mittels einer for-Schleife einzeln ausgegeben.

Lottozahlen = [ 7, 17, 24, 28, 29, 31 ]
for i in Lottozahlen:
    print(i)
Einzelne Elemente der Liste lassen sich über die rechteckigen Klammern zugreifen. In die rechteckige Klammer wird die Position des gewünschten Elements der Liste gesetzt. Hier gelten die gleichen Regeln wie schon bei der Sequenz.

Änderung von Listenelementen

Die Listenelemente können nicht nur gelesen, sondern auch geschrieben werden. Hier wird das Listenelement an der Position 3 durch 27 ersetzt.
Lottozahlen = [ 7, 17, 24, 28, 29, 31 ]
Lottozahlen[3] = 27
for i in Lottozahlen:
    print(i)
Falls Sie überrascht sind, dass die 28 statt der 24 durch die 27 ersetzt wurde, haben Sie nicht berücksichtigt, dass die Positionsnummern bei 0 beginnen.

Die Listen können nicht nur für Zahlen, sondern auch für Zeichenketten verwendet werden.

Stadt = [ "Arnis", "Paris", "Tokio", "New York" ]
for i in Stadt:
    print(i)
Wie schon erwähnt, können Listen auch unterschiedliche Typen aufnehmen.
WasAuchImmer = [ "Arnis", 42, "New York" ]
for i in WasAuchImmer:
    print(i)
print(WasAuchImmer[1]*2)
Tatsächlich liefert die unterste Zeile eine numerische Multiplikation. Solche gemischten Listen könnte man zum Modellieren eines realen Objekts verwenden, beispielsweise eines Autos. Dann könnte jeweils das erste Element die Marke, der zweite das Modell, das dritte die Leistung und so weiter darstellen. Hier eignet sich allerdings eher eine Klasse.

Referenz auf eine Liste

Wenn Sie eine Liste einer anderen Liste zuweisen oder eine Liste als Parameter an eine Funktion übergeben, entsteht keine Kopie, sondern eine Referenz. Es werden also nicht die Daten kopiert, sondern nur ein weiterer Verweis auf die eigentlichen Daten. Das ist natürlich schneller und hat aber zur Konsequenz, dass Änderungen am Duplikat auch beim Original erfolgen, weil es sich ja bei beiden um die Referenz auf die gleichen Daten handelt.

Operationen auf der Liste

Zwei Listen können mit dem Pluszeichen aneinander gehängt werden. Auch der Stern funktioniert bei Listen genauso wie bei Zeichenketten. Sie können damit eine Liste vervielfältigen.
lotto = [ 1, 4, 19, 23, 24, 35 ]
liste = lotto * 2
Die Variable liste enthält zwölf Elemente, nämlich zweimal hintereinander die Lottozahlen.

Die folgende Aufstellung geht davon aus, dass die Variable ls eine Liste ist.

Der Reißverschluss zip

Die Funktion zip() macht aus zwei Listen oder Sequenzen eine Liste von Tupeln, wobei es Paare aus den Elementen der beiden Listen erstellt. Am anschaulichsten ist die Wirkung der Funktion anhand eines Beispiels:
sequenz = "ABCDEF"
liste = [1, 2, 3, 4, 5]
tupelliste = zip(sequenz, liste)
print(tupelliste)
Die Ausführung dieses Programms ergibt folgende Ausgabe.
[('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5)]

Summe einer Liste

Besteht die Liste nur aus Zahlen, kann Sie der Funktion sum() übergeben werden, um die Summe der Zahlen zu ermitteln.

Die Argumentliste sys.argv

Eine besondere Liste ist die Liste der Aufrufparameter. Wird ein Python-Programm über die Kommandozeile aufgerufen, können ihm mehrere Parameter mit auf den Weg gegeben werden. Um auf diese aus dem Programm heraus zugreifen zu können, muss die Bibliothek sys eingebunden werden. Dann kann auf die Liste argv zugegriffen werden.
import sys
for i in sys.argv:
    print(i)
Das erste Element ist immer der Name des Python-Skripts selbst. Es folgen dann die Aufrufparameter.

Dictionaries

Ein Dictionary ermöglicht es, über einen Schlüsselbegriff nach Elementen zu suchen. Ein Dictionary wird mit geschweiften Klammern umgeben. Darin befindet sich eine durch Kommata getrennte Folge von Schlüsseln und Werten, die selbst wiederum durch einen Doppelpunkt getrennt sind. Ein naheliegendes Beispiel ist die Suche eines Kreises anhand des Autokennzeichens. Ein solches Nachschlagewerk würde folgendermaßen in Python realisiert:
kreis = {"SL":"Schleswig", "FL":"Flensburg","HG":"Bad Homburg"}
print(kreis["FL"])
Der Aufruf von print() würde in diesem Beispiel Flensburg liefern. Um ein Dictionary komplett auszulesen, kann wieder der Befehl for verwendet werden.
for i in kreis:
    print(i, kreis[i])
Wie man sieht, erhält die Laufvariable von for dabei den Schlüsselwert, über den dann aber leicht das Element zugegriffen werden kann.

Operationen auf dem Dictionary

Mit der Funktion items() wird aus dem Dictionary eine Liste von Tupeln aus Schlüsseln und Wert gebildet.
kreis = {"SL":"Schleswig", "FL":"Flensburg","HG":"Bad Homburg"}
liste = kreis.items()
print(liste)
Die Ausgabe ergibt folgendes:
[('FL', 'Flensburg'), ('HG', 'Bad Homburg'), ('SL', 'Schleswig')]
Die Funktion keys() liefert eine Liste aller Schlüssel eines Dictionarys.
kreis = {"SL":"Schleswig", "FL":"Flensburg","HG":"Bad Homburg"}
liste = kreis.keys()
print(liste)
Die Ausgabe ergibt folgendes:
['FL', 'HG', 'SL']
Analog liefert die Funktion values() eine Liste der Werte.

Mengen: set und frozenset

Mit set und frozenset bildet Python eine Menge nach. Eine Menge ist unsortiert. Jedes Element darf nur einmal enthalten sein. Während set veränderlich ist, ist frozenset, wie der Name schon vermuten lässt, unveränderbar. Eine leere Menge wird durch Initialisierung mit der Funktion set() erzeugt.
meineMenge = set() 
Ein Set kann durch eine Liste initialisiert werden. Das gleiche gilt für frozenset. Die Liste wird als Parameter übergeben.
meineMenge = set([1,12,34,38,39,40]) 
meineFesteMenge = frozenset([1,12,34,38,39,40]) 
Wird statt einer Liste eine Zeichenkette für die Initialisierung verwendet, enthält der Set die einzelnen Buchstaben der Zeichenkette. Dubletten werden dabei aussortiert, da eine Menge ja keine doppelten Elemente erlaubt.
>>> set("Hallihallo")
set(['a', 'i', 'H', 'l', 'o', 'h'])
Wenn Sie ein Dictionary für die Initialsierung einer Menge verwenden, enthält diese anschließend die Schlüssel.
>>> kreis = {"SL":"Schleswig", "FL":"Flensburg","HG":"Bad Homburg"}
>>> print(set(kreis))
set(['FL', 'HG', 'SL'])
>>>

Elemente und Mengen

Nach der Initialisierung kann einem set noch Elemente hinzugefügt oder entfernt werden. Die folgenden Funktionen stehen zur Verfügung:

Verknüpfung von Mengen

Die bekannten Operationen aus der Mengenleere lassen sich auch mit Python-Mengen ausführen.

Zwei Mengen können durch das Kleiner- und Größerzeichen verglichen werden. Dabei prüft der Ausdruck m1<m2, ob m1 eine echte Teilmenge von m2 ist. Der Gleichheitsoperator prüft, ob die Mengen die gleichen Elemente haben. Daraus ergibt sich dann logisch die Funktion der anderen Vergleichsoperatoren.

Der senkrechte Strich bewirkt das Erzeugen einer Vereinigungsmenge zweier Mengen. Die Ergebnismenge enthält also alle Elemente, die in mindestens einer der beiden Mengen enthalten sind.

vereinigung = menge | nochnemenge
Mit dem kaufmännischen Und, auch Ampersand genannt, erzeugen Sie die Schnittmenge zweier Mengen. Die Ergebnismenge enthält also alle nur Elemente, die in beiden Mengen enthalten sind.
schnitt = menge & nochnemenge
Das Minuszeichen erzeugt eine Differenzmenge aus zwei Mengen. Die erzeugte Menge enthält alle Elemente der ersten Menge, außer denen, die auch in der zweiten Menge enthalten sind.
diff = menge - nochnemenge
Mit dem Dachoperator wird die symetrische Differenz der Mengen erzeugt. Sie enthält nur die Elemente, die in genau einer der beiden Mengen vorhanden ist, also nicht in beiden.
symdiff = menge ^ nochnemenge

Operator Funktion
menge = erst <= zweit menge = erst.issubset(zweit)
menge = erst >= zweit menge = erst.issuperset(zweit)
menge = erst | zweit menge = erst.union(zweit)
menge = erst & zweit menge = erst.intersection(zweit)
menge = erst - zweit menge = erst.difference(zweit)
menge = erst ^ zweit menge = erst.symmetric_difference(zweit)
menge |= andere menge.update(andere)
menge &= andere menge.intersection_update(andere)
menge -= andere menge.difference_update(andere)
menge ^= andere menge.symmetric_difference_update(andere)

Wie bei allen Containern führt eine Zuweisung dazu, dass eine Referenz entsteht. Wird eine Kopie benötigt, wird die Memberfunktion copy() aufgerufen.

Variable Anzahl von Funktionsparameter

Mithilfe von Tupeln können Sie Funktionen eine variable Anzahl von Parametern verleihen. Die einfachste Version dies zu realisieren, ist dass Sie ein Tupel als Parameter verwenden. Im folgenden Beispiel ist der erste Parameter noch fest. Erst ab dem zweiten wird ein Tupel übergeben.
def calltupel(fest, tupelparameter):
    print(fest)
    for element in tupelparameter:
        print(element)

calltupel(12, (1, "Schau an", 3))
Sie müssen beim Aufruf natürlich darauf achten, dass die variablen Parameter in extra Klammern eingeschlossen sind, sonst meldet sich der Interpreter mit der Meldung, dass er deutlich weniger Parameter erwartet hatte.

Die andere Variante besteht darin, dass Sie die Tupel-Auflösung im Funktionskopf durchführen und einen Stern vor den Parameter setzen.

def tumehr(fest, *parameter):
    print(fest)  # nicht ueberraschend
    for element in parameter:
        print(element)

tumehr("Fest", 12, "locker")

Homepage (C) Copyright 2014, 2015 Arnold Willemer