Zum Inhalt springen

Datentypen

Aus Wikibooks

In diesem Kapitel beleuchten wir die Datentypen von Python und geben typische Operationen an, mit denen Variablen dieses Typs modifiziert werden können. Ein wichtiges Prinzip in Python ist das Duck-Typing[1]. Solange eine Variable jede Operation unterstützt, die von ihr gefordert wird, ist Python der Typ der Variablen egal.

Es ist auch möglich, Variable eines Datentyps in eine Variable eines anderen Typs zu konvertieren.

Die wichtigsten Datentypen in Python
Boolesche Werte Zahlen Sequenzen Mengen Assoziative Felder
bool int float complex list tuple range str set dict

Boolean

[Bearbeiten]

Der Datentyp bool repräsentiert Wahrheitswerte aus der Menge True und False. Werte dieses Datentyps werden zumeist bei Anfragen zurückgegeben, wie zum Beispiel: Enthält diese Zeichenkette ausschließlich Ziffern?. Die passende String-Methode hierzu heißt übrigens isdigit(). Ergebnisse werden zumeist im Zusammenhang mit Verzweigungen verwendet. Alle Vergleiche, wie a > b, b > 1, a == b usw. sind entweder True oder False, also vom Typ bool.

Viele andere Datentypen können auch als bool interpretiert werden, dabei werden leere Listen, Tupel, Mengen, Dictionarys, Strings, None und der Zahlenwert 0 ([], (), set(), {}, "", None, 0, 0.0) als False interpretiert; von 0 verschiedene Zahlen und nichtleere Sequenzen und Mengen haben den booleschen Wert True. Die Funktion bool(x) liefert den booleschen Wert von x, sofern er definiert ist.

Wahrheitswerte kann man mit Operatoren verknüpfen.

Die logischen Verknüpfungen haben wir in folgender Tabelle zusammengefasst, wobei a und b boolesche Variablen sind, die nur die Werte False und True annehmen können:

a b not a a and b a or b a != b (xor)
False False True False False False
False True True False True True
True False False False True True
True True False True True False
Für die logische Xor-Verknüpfung gibt es in Python kein Schlüsselwort, die Verknüpfung boolescher Werte mit != leistet aber das Gleiche; auch das bitweise xor ^ kann verwendet werden.

Ein Ausdruck wird so schnell wie es geht ausgewertet. Ist am Anfang eines komplizierten Ausdrucks schon klar, dass der Ausdruck einen bestimmten Wahrheitswert erhält, dann wird nicht weiter ausgewertet. Zum Beispiel wird True or (A and B) zu True ausgewertet, ohne dass der Ausdruck (A and B) berücksichtigt wird. Dieses Vorgehen ist insbesondere wichtig im Zusammenhang mit Funktionen, denn A und B können auch Funktionen sein, die in diesem Fall nicht aufgerufen werden. Gleiches gilt für False and (Ausdruck). Hier wird (Ausdruck) ebenfalls nicht berücksichtigt.

Zahlen

[Bearbeiten]

Zahlen sind Grundtypen in Python. Es gibt Zahlen unterschiedlicher Art. Hier folgt als Vorgriff auf die Erläuterungen ein gemeinsames Beispiel:

>>> 2**65
36893488147419103232

>>> # Gleitkommazahl
>>> 2.7 // 1.3
2.0
>>> 2**65.0
3.6893488147419103e+19

>>> # komplexe Zahl
>>> (5.0 + 2.0j)**2.0
(21+20j)

Ganze Zahlen

[Bearbeiten]

Der Datentyp für ganze Zahlen heißt int. Dieser hat in Python keine feste Länge; die maximal darstellbare Zahl ist nur durch die Speichergröße beschränkt. Hier folgt eine Auswahl der Dinge, die Sie mit ganzen Zahlen tun können:

Operation Bedeutung
+, -, *, ** Addieren, Subtrahieren, Multiplizieren und Potenzieren
/ Division, Ergebnis ist vom Typ float
// Ganzzahlige Division, es gilt immer a // b <= a / b,

Beispiele: 5 // 3 → 1, -5 // 3 → -2

% Modulo-Operation

Beispiele: 5 % 3 → 2, -5 % 3 → 1

divmod(x, y) gibt das Tupel (x // y, x % y) zurück; es gilt immer (x // y) * y + (x % y) == x
&, |, ^ bitweises and, or, xor
n << k verschiebt n um k Bit nach links
n >> k verschiebt n um k Bit nach rechts
pow(n, k, m) berechnet nk mod m (effizienter als (n**k) % m)
(Zahl).bit_length() Anzahl der Bits der Binärdarstellung der Zahl ab dem ersten 1-Bit, z. B. (8).bit_length() ergibt 4 (8 = 0b1000)
abs(Zahl) berechnet den Absolutbetrag der Zahl.
bin(Zahl) liefert die binäre Darstellung der Zahl als String mit Präfix '0b'.
hex(Zahl) liefert die hexadezimale Darstellung der Zahl als String mit Präfix '0x' .
oct(Zahl) liefert die oktale Darstellung der Zahl als String mit Präfix '0o'.
chr(Zahl) liefert das Zeichen mit dem "ASCII"-Code Zahl, z. B. chr(97) liefert 'a'.

Das Modul "math" enthält einige mathematische Funktionen für ganze Zahlen, zum Beispiel gcd (größter gemeinsamer Teiler).

Gleitkommazahlen

[Bearbeiten]

Der Typ float repräsentiert Gleitkommazahlen. Diese Zahlen werden mit einem Dezimalpunkt, Exponent oder mit beiden notiert; Beispiele: 1e-23, -.5, 2., 5.6E78. Folgende Operationen sind auf Gleitkommazahlen definiert:

Operation Bedeutung
+, -, *, ** Addieren, Subtrahieren, Multiplizieren und Potenzieren
/ Normale Division
// entspricht der ganzzahligen Division. Das Ergebnis wird als Gleitkommazahl dargestellt.
% Modulo-Operation
round(Zahl) (ohne Angabe der Stellenzahl) rundet die Zahl kaufmännisch zur nächstgrößeren/-kleineren ganzen Zahl.

Mathematische Funktionen, hauptsächlich für den Datentyp float, stellt das Modul "math" bereit.

Komplexe Zahlen

[Bearbeiten]

Komplexe Zahlen[2] bestehen aus Realteil und Imaginärteil. In Python heißt der zugehörige Datentyp complex und wird als Summe von Realteil und Imaginärteil mal imaginäre Einheit dargestellt, beispielsweise C = 5.0 + 2.0j. Das Symbol für die imaginäre Einheit ist j und muss ohne Leerzeichen hinter die Zahl geschrieben werden.

Folgende Dinge kann man mit komplexen Zahlen tun:

Operation Bedeutung
+, -, *, /, ** Addieren, Subtrahieren, Multiplizieren, Dividieren und Potenzieren
abs(C) Berechnet den Absolutbetrag der komplexen Zahl C
C.real, C.imag gibt den Realteil, Imaginärteil der Zahl C zurück.
C.conjugate() gibt die konjugiert komplexe Zahl zurück (C.real, -C.imag)

Mathematische Funktionen für den Datentyp complex stellt das Modul "cmath" bereit.

Strings

[Bearbeiten]

Ein String ist eine Folge von Zeichen; der zugehörige Datentyp heißt str. Stringliterale werden in Paare von Anführungszeichen (") oder Hochkommas (') eingeschlossen. Soll das selbe Anführungszeichen auch im String vorkommen, muss ein Backslash (\) vorangestellt werden; das jeweils andere Anführungszeichen kann ohne weiteres im String verwendet werden.

Mehrzeilige Strings werden in Paare dreifacher Anführungszeichen (""") eingeschlossen.

Anders als in anderen Sprachen kann man einen String nicht mehr verändern. Stringoperationen und -funktionen erzeugen neue Strings.

# Stringoperationen * und +
>>> "Hallo "*2 + "Welt" + "!"
'Hallo Hallo Welt!'
>>> s = """
...
... Dieses ist ein langer String, er geht
... über mehrere Zeilen. Es steht zwar nichts interessantes
... darin, aber darauf kommt es auch nicht an."""
>>> print(s)


Dieses ist ein langer String, er geht
über mehrere Zeilen. Es steht zwar nichts interessantes
darin, aber darauf kommt es auch nicht an.

Strings können also zusammengesetzt werden, wobei gerade die Methode mit "Hallo "*2 einen neuen String zu erzeugen, ungewohnt aber direkt erscheint. Lange Strings werden ebenso gebildet wie ein Kommentar, mit dem Unterschied, dass er einer Variable zugewiesen wird. Tatsächlich sind Kommentare, die mit """ gebildet werden nichts anderes, als anonyme Strings.

Auf String-Objekte kann man Methoden anwenden. Diese geben einen Ergebnis-String zurück und lassen das Original unverändert:

>>> s = "dies ist mein kleiner String"
>>> s.capitalize()
'Dies ist mein kleiner string'
>>> s.replace("kleiner", "kurzer")
'dies ist mein kurzer String'
>>> s.upper()
'DIES IST MEIN KLEINER STRING'

Einige der Methoden, die auf ein String-Objekt s anwendbar sind, finden sich in folgender Tabelle:

Methode Beschreibung
s.count(Substring, Anfang, Ende) Zählt die Vorkommen von Substring im Objekt. Anfang und Ende sind optional
s.find(Substring, Anfang, Ende) Findet das erste Vorkommen von Substring, gibt den Index innerhalb des Strings oder -1 zurück. Anfang und Ende sind optional.
s.replace(Alt, Neu, Anzahl) Ersetzt im String Alt gegen Neu. Nur die ersten Anzahl Vorkommen werden ersetzt. Anzahl ist optional.
s.capitalize() Erzeugt einen neuen String, dessen erster Buchstabe groß geschrieben ist.
s.lower() Gibt einen String zurück, der nur aus Kleinbuchstaben besteht
s.upper() Gibt einen String zurück, der nur aus Großbuchstaben besteht.
s.strip(Zeichen) Entfernt die Vorkommen von Zeichen am Anfang und am Ende vom String. Wenn Zeichen nicht angegeben wird, so wird Leerzeichen angenommen.
s.isalnum() True, wenn der String aus Ziffern und Buchstaben besteht
s.isalpha() True, wenn der String aus Buchstaben besteht.
s.isdigit() True, wenn der String aus Ziffern besteht.
s.startswith(prefix, start, end)
s.endswith(suffix, start, end)
True, wenn der String mit prefix beginnt bzw. mit suffix endet. Die optionalen Parameter start und end begrenzen den Suchbereich.
s.split(Trenner) Zerlegt einen String in Teilstrings. Trenner ist optional; ohne Angabe wird bei Leerzeichen, Tabulatoren und Zeilenumbrüchen getrennt.
s.join(Liste) Fügt eine Liste von Strings zu einem String zusammen. Trenner.join(s.split(Trenner)) sollte genau den String s wiedergeben.

Das ist allerdings nur ein kleiner Teil der Methoden des Datentyps str; in Python 3.12 gibt es über 40 davon.

Mehr über Operatoren und Methoden für Strings erfahren Sie im Abschnitt Sequenzen.

Escape-Sequenzen

[Bearbeiten]

Escape-Sequenzen dienen dazu, nicht druckbare Zeichen und Sonderzeichen in einen String aufzunehmen; sie beginnen in Python mit dem Backslash \.

Folgende Escape-Sequenzen sind in Python definiert:

Escape-Sequenz Ergebnis Bezeichnung
\\ \ Backslash
\' ' Hochkomma
\" " Anführungszeichen
\b Backspace (BS)
\n ASCII Linefeed (LF)
\r ASCII Carriage Return (CR)
\t Tabulator (TAB)
\xb5 µ Hexadezimalcode
\265 µ Oktalcode
u00B5 µ Unicode 16 bit
U000000B5 µ Unicode 32 bit
N{integral} Unicodezeichen-Name

Die Werte und Zeichen in den letzten fünf Zeilen der Tabelle sind als Beispiele zu verstehen.

raw-Strings

[Bearbeiten]

Wenn vor einem String-Literal ein r steht, werden Backslash-Zeichen nicht als Beginn einer Escape-Sequenz interpretiert, sondern in den String aufgenommen. Das ist besonders nützlich, wenn der String viele Backslashs enthalten soll, wie das zum Beispiel für reguläre Ausdrücke erforderlich ist. Auf einen Backslash folgende Anführungszeichen werden ebenfalls aufgenommen. Einschränkung: solche Strings können nicht mit einer ungeraden Zahl von Backslashs enden; bei Bedarf kann aber ein Backslash mit + "\\" angehängt werden.

Beispiel:

>>> pattern = r"\d+\s\d+"
>>> pattern
'\\d+\\s\\d+'

Zeichen

[Bearbeiten]

Zeichen sind in Python nichts anderes als Strings der Länge Eins. Wir führen sie hier auf, um zwei Funktionen, die Zeichen als Parameter erwarten bzw. als Ergebnis liefern, nämlich ord(Zeichen) und chr(Zahl), vorzustellen: ord(Zeichen) liefert eine Zahl, die der internen Darstellung des Zeichens entspricht, während chr(Zahl) ein Zeichen zurückliefert, welches zur angegebenen Zahl passt.

>>> print("'A' hat den numerischen Wert", ord('A'))
'A' hat den numerischen Wert 65
>>> print("Das Zeichen mit der Nummer 100 ist '" + chr(100) + "'")
Das Zeichen mit der Nummer 100 ist 'd'

Teilweise werden Strings der Länge Eins in Fehlermeldungen auch als "char" oder "character" bezeichnet, obwohl es Datentypen mit diesen Bezeichnungen nicht gibt.

Zahlenfolgen

[Bearbeiten]

Zur Steuerung von Schleifen wird häufig ein range-Objekt verwendet, dieses liefert in jedem Schleifendurchlauf einen Wert aus einer Folge ganzer Zahlen. Parameter sind 'stop' und optional 'start' und 'step', dabei beginnt die Folge immer mit start (Default = 0), und stop ist nie enthalten:

  • range(stop) liefert alle Zahlen von 0 bis ausschließlich stop, Beispiel: range(10) liefert nacheinander 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
  • range(start, stop) liefert alle Zahlen von start bis ausschließlich stop, Beispiel: range(1, 4) liefert nacheinander 1, 2, 3.
  • range(start, stop, step) liefert die Zahlen von start bis ausschließlich stop mit Schrittweite step, Beispiel: range(-1, 9, 2) liefert nacheinander -1, 1, 3, 5, 7.
    • Der Parameter step darf auch negativ (aber nicht 0) sein, stop ist auch dann nicht in der Folge enthalten, Beispiel: range(8, 0, -2) liefert nacheinander 8, 6, 4, 2.

Weitere Beispiele sind im Abschnitt Listen zu finden.

Mehr über Methoden für range-Objekte erfahren Sie im Abschnitt Sequenzen.

Listen

[Bearbeiten]

Listen sind veränderbare Objekte, die dazu dienen, zur selben Zeit Elemente beliebigen Typs aufzunehmen. Der Datentyp heißt list. Leere Listen können mit list() und [] erzeugt werden.

>>> Werte = ['Text', 'Noch ein Text', 42, 3.14]
>>> print(Werte)
['Text', 'Noch ein Text', 42, 3.14]
>>> print("Anzahl der Elemente: ", len(Werte))
Anzahl der Elemente:  4

Die Funktion len() bestimmt die Anzahl der Elemente der Liste, in diesem Fall 4. Listen können auch Listen enthalten, auch sich selbst.

Hinzugefügt werden Werte mit dem +-Operator und den Funktionen append() und insert():

>>> Werte = ['Text', 42]
>>> Werte += ['foo']
>>> Werte.append(3)
>>> Werte.insert(2, 111)
>>> Werte
['Text', 42, 111, 'foo', 3]

Diese Funktionen nennt man Methoden, da sie Bestandteil der Listenobjekte sind. Die Methode insert(2, 111) fügt vor dem Element mit dem Index 2 die Zahl 111 ein. Die Zählung beginnt mit 0, das Element mit Index 0 ist im obigen Beispiel die Zeichenkette Text.

Löschen lassen sich Listenelemente ebenfalls:

>>> Werte = [1, 2, 'Meier', 4, 5]
>>> Werte.pop()
5
>>> Werte.pop(0)
1
>>> Werte.remove('Meier')
>>> Werte
[2, 4]

Die Methode pop() ohne Argument liefert das letzte Element der Liste und entfernt es aus der Liste; mit Argument N wird das Element mit Index N gelöscht. Die Methode remove(x) entfernt das erste Element mit dem Wert x.

Listen lassen sich auch per Funktion erzeugen. Eine solche Funktion ist range(Startwert, Endwert, Schrittweite). Sie erwartet einen Startwert sowie einen Endwert erzeugt daraus eine entsprechende Folge ganzer Zahlen, wobei der Endwert nicht Teil der Zahlenfolge ist. Die Parameter Startwert und Schrittweite sind optional, Defaultwerte sind 0 für den Startwert und 1 für die Schrittweite.

>>> l1 = [i for i in range(1, 10)]      # oder [*range(1, 10)]
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l2 = [i for i in range(1, 10, 3)]   # oder [*range(1, 10, 3)]
>>> l2
[1, 4, 7]

In unserem Beispiel enthält l1 alle Werte von 1 bis 9, l2 hingegen enthält lediglich 1, 4 und 7, weil wir eine Schrittweite von 3 angegeben haben. Im Gegensatz zu Python2 legt die range-Funktion in Python3 nicht die gesamte Liste, sondern ein range-Objekt an.

Die oben beschriebene Methode, Listen mit Inhalt zu erzeugen, heißt auf Englisch "list comprehension".

Weitere Möglichkeiten:

  • Die Aufnahme von Objekten in die Liste kann auch von einer zusätzlichen Bedingung abhängig gemacht werden.
  • Es können mehrere Schleifen kombiniert werden.

Beispiele:

>>> l3 = [n for n in range(3, 25, 2) if n % 3]                                  # nur ungerade, nicht durch 3 teilbare Zahlen
>>> l3
[5, 7, 11, 13, 17, 19, 23]
>>> l4 = [(x, y, z) for x in range(2) for y in range(2) for z in range(2)]      # alle Tripel aus 0 und 1
>>> l4
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]

Einige der Methoden, die auf ein list-Objekt L anwendbar sind, finden sich in folgender Tabelle:

Methode Beschreibung
L.pop(n) entfernt das Listenelement mit Index n bzw. das letzte Element, wenn kein Index angegeben wurde
L.copy() gibt eine Kopie der Liste zurück
L.insert(n, a) fügt ein neues Objekt a vor dem Listenelement mit Index n ein
L.clear() leert die Liste
L.extend(L2) hängt die Elemente der Liste L1 ans Ende der Liste
L.append(a) hängt das Objekt a ans Ende der Liste
L.remove(a) entfernt das erste Listenelement mit Wert a
L.reverse() kehrt die Reihenfolge der Listenelemente um
L.sort() sortiert die Elemente der Liste, sofern Vergleichsoperationen definiert sind, z.B. wenn die Liste nur Zahlen oder nur Strings enthält

Mehr über Operatoren und Methoden für Listen erfahren Sie im Abschnitt Sequenzen.

Tupel

[Bearbeiten]

Tupel (Datentyp tuple) lassen sich, anders als Listen, nicht verändern. Sie sind damit besonders geeignet, um Konstanten zu repräsentieren. Ansonsten ähneln sie Listen aber sehr:

>>> Werte = (9876, 913.0, 42, 3.14)
>>> print(min(Werte))
3.14
>>> print(max(Werte))
9876
>>> print("Anzahl der Elemente: ", len(Werte))
Anzahl der Elemente:  4

Ein Tupel wird in runde Klammern geschrieben; auch Tupel mit nur einem Element sind möglich, dafür muss ein Komma nach dem Element stehen, um das Tupel von einem Ausdruck in Klammern zu unterscheiden, z.B. (1,).

Mehr über Operatoren und Methoden für Tupel erfahren Sie im Abschnitt Sequenzen.

Sequenzen

[Bearbeiten]

Zu Sequenzen zählen die hier behandelten Strings, Listen und Tupel. Lediglich Listen lassen sich ändern, alle anderen Sequenztypen sind konstant. Grund genug, einige Details zusammenzufassen; die unten genannten Methoden und Funktionen sind auch auf range-Objekte anwendbar.

Sequenzen können aufgezählt werden. Das erste Element hat den Index 0, das letzte Element den Index len(Sequenz)-1. Sequenzen können ihrerseits wieder Sequenzen aufnehmen. Eine Besonderheit ist, dass man Teilsequenzen, so genannte Slices, bilden kann:

>>> text = "Dies ist mein String"
>>> print("Großbuchstaben: ", text[0], text[14])
Großbuchstaben:  D S
>>> print("Verb: ", text[5:8])
Verb:  ist
>>> print("Erstes Wort: ", text[:4])
Erstes Wort:  Dies
>>> print("Letztes Wort: ", text[14:])
Letztes Wort:  String

An diesem Beispiel sieht man, dass man einzelne Zeichen direkt adressieren kann, wobei man den Index in eckige Klammern setzt, wie auch einen Bereich der Sequenz ansprechen kann, indem Anfang und Ende durch Doppelpunkt getrennt werden. Anfang und Ende vom Slice sind optional. Steht vor dem Doppelpunkt kein Wert, so ist der Anfang der Sequenz gemeint. Analoges gilt für das Ende. Optional kann auch nach einem zweiten Doppelpunkt eine Schrittweite angegeben werden, [::2] wäre zum Beipiel jedes zweite Element, [::-1] die Sequenz von hinten nach vorne. Wenn Sie diese Art der Adressierung verstanden haben, fällt es Ihnen sicher leicht, die negative Adressierung ebenfalls zu verstehen:

>>> sequenz = (1, 2, 'a', 'b', 'c')
>>> print("Buchstaben: ", sequenz[-3:])
Buchstaben:  ('a', 'b', 'c')
>>> print("Buchstaben: ", *sequenz[-3:])        # entspricht print("Buchstaben: ", 'a', 'b', 'c')
Buchstaben:  a b c
>>> print("Ziffern: ", sequenz[:-3])
Ziffern:  (1, 2)
>>> print("Jedes 2. Element:", sequenz[::2])
Jedes 2. Element: (1, 'a', 'c')

Buchstabenindizes werden hier vom Ende gezählt. Der Index -1 ist das c, der Index -2 ist das b und so weiter. Die Buchstaben werden also vom drittletzten zum letzten hin ausgegeben. Ziffern hingegen werden vom Nullten zum ebenfalls drittletzten ausgegeben, wobei ebendieses nicht mit ausgegeben wird.

Mit einem vorangestellten Stern * werden Sequenzen in einzelne Elemente zerlegt und können so als eine Folge von Parametern an eine Funktion (wie print im Beispiel) übergeben oder in eine neue Liste übernommen werden.

Auf Sequenzen sind gemeinsame Operatoren und Methoden definiert. Folgende Tabelle gibt einen Überblick:

Funktion/Methode Beschreibung Beispiel Ergebnis
S + T Die Sequenzen S und T werden aneinandergehängt.
Nicht auf range-Objekte anwendbar.
(1, 2, 3) + (2,) (1, 2, 3, 2)
S * n Erzeugt eine Sequenz, die aus der n-fachen Aneinanderreihung von S besteht.
Nicht auf range-Objekte anwendbar.
(3,) * 4, "Hallo " * 2 (3, 3, 3, 3), 'Hallo Hallo '
a in S True, wenn Element a in der Sequenz S vorkommt 3 in [0] * 7 False
len(S) Länge, Anzahl der Elemente von S len("Hallo, Welt!") 12
S.count(a) Zählt die Vorkommen von a im Objekt S. "Hallo, Welt!".count("l") 3
S.index(a) Index des ersten Vorkommens von a im Objekt S. "Hallo, Welt!".index("l") 2
min(), max() Bestimmt das Minimum/Maximum der Sequenz min((1, 2, 3)), max(['a', 'b', 'c']) 1, 'c'
any(S) True, wenn mindestens ein Element E von S nicht 0, False, None oder eine leere Sequenz wie "" ist, also bool(E) == True ist any([0, 0, 99, 0]) True
all(S) True, wenn für alle Elemente E von S bool(E) == True ist all([42, ""]) False
S == T True, wenn die Sequenzen S und T vom gleichen Typ sind und S[i] == T[i] für alle i gilt. [3, 2, 1] == [3, 2, 1] True
S != T True, wenn die Sequenzen S und T obengenannte Bedingungen nicht erfüllen. [3, 2, 1] != (3, 2, 1) True

Der Typ set beschreibt Mengen. Elemente einer Menge sind ungeordnet und einzigartig. Leere Sets werden mit set() erzeugt. Alle Sets unterstützen die üblichen Mengenoperationen:

>>> s1 = set('abc')
>>> s2 = set('bcd')
>>> print('s1 =', s1,' s2 =', s2)
s1 = {'b', 'a', 'c'}  s2 = {'b', 'c', 'd'}
>>> # Differenzmenge
>>> print('s1 - s2 =', s1 - s2)
s1 - s2 = {'a'}
>>> # Vereinigungsmenge
>>> print('s1 | s2 =', s1 | s2)
s1 | s2 = {'b', 'c', 'a', 'd'}
>>> # Schnittmenge
>>> print('s1 & s2 =', s1 & s2)
s1 & s2 = {'b', 'c'}
>>> # Symmetrische Differenz
>>> print('s1 ^ s2 =', s1 ^ s2)
s1 ^ s2 = {'a', 'd'}
>>> # Enthalten
>>> print("'a' in s1 =", 'a' in s1)
'a' in s1 = True
>>> # Mächtigkeit der Menge
>>> print("len(s1) = ", len(s1))
len(s1) =  3

Die Operation in liefert als Ergebnis True wenn ein Element in der Menge vorkommt.

Folgende Methoden lassen sich von einem Set-Objekt ansprechen:

Methode Operator Beschreibung
s1.difference(s2) - Differenzmenge, s1 - s2
s1.intersection(s2) & Schnittmenge, s1 & s2
s1.issubset(s2) <= Teilmenge, s1 <= s2: s1 ist Teilmenge von s2 und kann auch gleich s2 sein
< echte Teilmenge, s1 < s2: s1 ist Teilmenge von s2 aber nicht gleich s2
s1.issuperset(s2) >= Übermenge, s1 >= s2
> echte Übermenge, s1 > s2
s1.union(s2) | Vereinigungsmenge, s1 | s2
s1.symmetric_difference(s2) ^ Symmetrische Differenz, s1 ^ s2 enthält die Elemente, die in s1 oder s2 aber nicht in beiden Mengen enthalten sind.
s.add(E) |= Fügt dem Set s das Element E hinzu
s.remove(E) Entfernt das Element E aus dem Set; wenn das Set E nicht enthält, wird die Exception KeyError ausgelöst.
s.discard(E) -= Entfernt das Element E aus dem Set, wenn es enthalten ist; wenn das Set E nicht enthält, wird keine Exception ausgelöst.

Dictionarys

[Bearbeiten]

Der Typ dict stellt eine Zuordnung zwischen Schlüsseln und Werten her. Er ist wie ein Wörterbuch zu verstehen, wo als Schlüssel zum Beispiel ein englischer Begriff und als Wert ein deutschsprachiger Begriff aufgeführt ist. Auf die Werte wird mit Name[Schlüssel] zugegriffen, ähnlich wie bei Listen, nur dass der Schlüssel auch von einem anderen Typ als int sein kann. Selbstverständlich lassen sich auch Telefonnummern oder Gehälter auf diese Weise ordnen:

>>> personal = {'Tom' : 32000, 'Beate' : 44000, 'Peter' : 10000}
>>> print(personal)
{'Tom': 32000, 'Beate': 44000, 'Peter': 10000}
>>> print("Tom verdient %d Euro pro Jahr" % (personal['Tom']))
Tom verdient 32000 Euro pro Jahr

Leere Dictionarys werden mit dict() oder {} erzeugt. Dictionarys können modifiziert werden.

>>> personal = {'Tom' : 32000, 'Beate' : 44000, 'Peter' : 10000}
>>> print(personal)
{'Tom': 32000, 'Beate': 44000, 'Peter': 10000}
>>> print("Susi kommt dazu...", end="")
Susi kommt dazu...>>> personal['Susi'] = 10000
>>> print(personal.keys())
dict_keys(['Tom', 'Beate', 'Peter', 'Susi'])
>>> print("Peter hat einen anderen Job gefunden...")
Peter hat einen anderen Job gefunden...
>>> del personal['Peter']
>>> print(personal.keys())
dict_keys(['Tom', 'Beate', 'Susi'])
>>> print("Tom bekommt mehr Geld: ", end="")
Tom bekommt mehr Geld: >>> personal['Tom'] = 33000
>>> print(personal)
{'Tom': 33000, 'Beate': 44000, 'Susi': 10000}

Einträge kann man hinzufügen, indem man Name[Schlüssel] einen Wert zuweist. Mit del(Name[Schlüssel]) lassen sich Schlüssel/Wert-Paare löschen.

Folgende Tabelle zeigt darüber hinaus noch einige gebräuchliche Dictionary-Methoden:

Methode Beschreibung
D.get(Schlüssel) Liefert den Wert für Schlüssel
Schlüssel in D True, wenn Schlüssel im Dictionary D vorkommt
D.items() Gibt den Inhalt als Liste von (Schlüssel, Wert)-Tupeln zurück
D.keys() liefert alle Schlüssel als Liste
D.values() analog zu keys(), liefert alle Werte als Liste
D.pop(Schlüssel) Gibt den Wert für Schlüssel zurück und entfernt Schlüssel/Wert


Besonderheiten beim Kopieren

[Bearbeiten]

Beim Kopieren von Variablen zusammengesetzter Datentypen, wie zum Beispiel Listen, gibt es eine Besonderheit. Die Kopien verweisen wieder auf die Originale. Versucht man nun, eine Kopie zu verändern, verändert man gleichzeitig das Original, wie folgendes Beispiel zeigt:

liste1 = [1, 2, 3]
liste2 = liste1
liste2 += [5]

print(liste1)
print(liste2)
print(liste2 is liste1)    # True, wenn liste2 und liste1 dasselbe Objekt bezeichnen

Statt zweier unterschiedlicher Listen bekommen wir dieses erstaunliche Ergebnis:

[1, 2, 3, 5]
[1, 2, 3, 5]
True

Wir haben also gar keine Kopie bearbeitet, sondern nur die einzig vorhandene Liste, auf die sowohl liste1 als auch liste2 nur verweisen.

Lösung des Problems: liste2 = liste1[:], ein Slice über die komplette Liste. Für andere Datentypen (aber auch Listen) gibt es aus dem Modul copy die Funktion copy(). Dictionarys und Listen haben eine eigene copy()-Methode. All dieses erzeugt aber nur eine flache Kopie. Sollen auch z. B. Listen mit kopiert werden, die in einer Liste enthalten sind, verwendet man die Funktion copy.deepcopy(). Hierzu noch ein Beispiel:

>>> import copy
>>>
>>> tupel1 = (1, 2, [3, 4], 5)
>>> tupel2 = copy.deepcopy(tupel1)
>>> #tupel2 = copy.copy(tupel1)   # zum Testen auskommentiert
>>> tupel2[2].append("foo")
>>>
>>> tupel1
(1, 2, [3, 4], 5)
>>> tupel2
(1, 2, [3, 4, 'foo'], 5)
>>> import copy
>>>
>>> tupel1 = (1, 2, [3, 4], 5)
>>> #tupel2 = copy.deepcopy(tupel1)   # zum Testen auskommentiert
>>> tupel2 = copy.copy(tupel1)
>>> tupel2[2].append("foo")
>>>
>>> tupel1
(1, 2, [3, 4, 'foo'], 5)
>>> tupel2
(1, 2, [3, 4, 'foo'], 5)

Mit copy.deepcopy erhält man also eine eigenständige Kopie inklusive der enthaltenen Liste.

Das Beispiel zeigt auch nochmal, dass zwar Tupel unveränderlich sind, aber enthaltene veränderliche Datentypen gleichwohl auch veränderlich bleiben. Die Problematik des Kopierens ist also nicht auf veränderliche Datentypen beschränkt.

Konvertierung

[Bearbeiten]

Für jeden Datentyp gibt es in Python eine gleichnamige Funktion, die ein Objekt dieses Typs anlegt, list() erzeugt zum Beispiel eine leere Liste. Solche Funktionen werden Konstruktor genannt und können in vielen Fällen zur Konvertierung genutzt werden. Aus einem String kann zum Beispiel eine Zahl werden, wenn der String nur Ziffern enthält. Andernfalls wird eine Fehlermeldung beim Versuch der Konvertierung ausgegeben. Die folgende Tabelle enthält einige Konvertierungsfunktionen:

Funktion Konvertiert von Konvertiert nach Beispiel Ergebnis
int() str, float ganze Zahl int("33") 33
float() str, int Gleitkommazahl float(1) 1.0
str() (fast) beliebig String str(3.14) '3.14'
set() Sequenz set set([1, 2, 3]) {1, 2, 3}

Typenabfrage

[Bearbeiten]

Den Typ einer Variablen kann man mit Hilfe der Funktion type() abfragen:

>>> type(3)
<class 'int'>
>>> type('a')
<class 'str'>
>>> type(("Hallo", "Welt"))
<class 'tuple'>
>>> type(["Hallo", "Welt"])
<class 'list'>
>>> type({"Hallo" : 1, "Welt" : 2})
<class 'dict'>

Mit Hilfe der Funktion isinstance kann man prüfen, ob eine Variable von einem bestimmten Typ ist:

>>> isinstance(False, bool)
True
>>> isinstance(0.5, (int, float))    # int oder float
True

Zusammenfassung

[Bearbeiten]

Sie haben jetzt einen Überblick über das Typensystem von Python. Vom Prinzip her braucht man sich über den Typ meistens keine Gedanken zu machen, sollte jedoch in Spezialfällen darüber Bescheid wissen. Einer Variablen weist man Werte zu und schon steht der Typ fest. Den Typ einer Variablen kann man zur Laufzeit ändern und abfragen.

Anmerkungen

[Bearbeiten]
  1. Wenn etwas so aussieht wie eine Ente (oder ein Datentyp), so geht wie eine Ente und so quakt wie eine Ente, warum soll es dann keine sein?
  2. Um mehr Hintergrundinformationen über komplexe Zahlen zu bekommen, empfehlen wir ihnen das Wikibuch Komplexe Zahlen.

Seitentitel: Python/ Datentypen
(Python/ Datentypen)
(Python/ Datentypen)