4. Datentypen
Dieser Abschnitt behandelt die in Python vorhandenen Grunddatentypen und
einige der auf ihnen möglichen Operationen. Nach einer Beschreibung
der numerischen Datentypen werde ich vor allem auf die Sequenztypen eingehen.
Zu beachten ist, daß es in Python keine statische Typisierung
gibt und eine Variable somit Objekte jeden Typs aufnehmen kann.
Numerische Datentypen
Dazu gehören:
-
integer
Sie entsprechen mit 32bit Länge dem Typ long in C
-
long integer
Dieser numerische Typ hat die Besonderheit, daß seine Genauigkeit
nicht beschränkt ist.
Zur Unterscheidung von long integers von normalen (plain)
integers
wird an den Zahlenwert ein 'L' oder 'l' angehängt.
-
floating point
Gleitkommazahlen werden in Objekten des Typs floating point
gespeichert. Deren Genauigkeit ist implementationsabhängig.
-
complex
Um komplexe Zahlen zu modellieren, werden zwei floating points
im neuen Typ complex gekapselt. Dabei wird der Imaginärteil
immer durch das Suffix 'J' bzw. 'j' gekennzeichnet.
Arithmetische Operatoren:
Die meisten Operatoren sind sie gleichen wie in anderen bekannten Sprachen;
der Vollständigkeit halber habe ich die wichtigsten dennoch aufgeführt.
Operator |
Typ |
Beschreibung |
+ |
unär |
ändert gar nichts an der Zahl |
- |
unär |
ändert das Vorzeichen der Zahl |
~ |
unär |
bitweise Inversion, nur auf (long) integers anwendbar |
** |
binär |
der power-Operator |
* |
binär |
Multiplikation |
+ |
binär |
Addition |
- |
binär |
Subtraktion |
/ |
binär |
Division (bei (long) integers ganzzahlig) |
% |
binär |
Modulo |
<< |
binär |
Linksshift eines (long) integer |
>> |
binär |
Rechtsshift eines (long) integer |
& |
binär |
bitweises AND |
| |
binär |
bitweises OR |
^ |
binär |
bitweises XOR |
and |
binär |
logisches AND |
or |
binär |
logisches OR |
not |
unär |
logisches NOT |
Die Vergleichsoperatoren funktionieren wie in C, allerdings sind zusätzlich
beliebig lange Vergleichsketten möglich (z.B. (x < y <=
z != a == b > c), was (x<y) and (y<=z) and (z!=a) and (a==b)
and (b>c) entspricht).
Sequentielle Datentypen
Die sequentiellen Datentypen enthalten immer eine Sequenz von Elementen,
die einzeln angesprochen werden können. Die in Python integrierten
Typen sind String, List, Tuple und Dictionary.
Mittels Slice-Notation können Teilsequenzen extrahiert werden.
Dazu gibt man ein Wertepaar [u:o] an, das die Bereichsgrenzen
anzeigt. Das Ergebnis ist die Sequenz mit allen Werten vom Wert an der
Untergrenze u bis zum letzten Wert vor der Obergrenze o.
Ist u>=o, wird eine leere Sequenz erzeugt. Wenn u bzw. o nicht angegeben
wird, setzt der Interpreter 0 bzw. die Länge der Originalsequenz als
Standardwert ein.
Für negative Werte von u und o wird bei der Indizierung vom Ende
der Sequenz an zu zählen begonnen.
Es gilt:
seq[:] == seq[0:len(seq)] == seq
seq[:i] + seq[i:] == seq
Beispiel (seq = 'abcde'):
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
0 1 2 3 4
5
-5 -4 -3 -2 -1
seq[1:2] == 'b'
seq[-4:-3] == 'b'
seq[:4] == 'abcd'
seq[2:] == 'cde'
seq[2:-1] == 'cd'
seq[:] == 'abcde'
String
String stellt eine Folge einzelner Zeichen dar. Den Typ char
gibt es in Python nicht, daher ist jedes Einzelzeichen ebenfalls ein String.
Die Zeichenfolge kann in einfache ('), doppelte (") und dreifache ("""
bzw. ''') Anführungszeichen eingeschlossen sein. Die beiden ersten
Formen sind äquivalent, die letztere erlaubt auch Strings, die mehrere
Zeilen umfassen. Das Zeilenende kann allerdings auch wie in C mit \n
codiert werden.
Andere Sonderzeichen können ebenfalls mit vorangestelltem Backslash
verwendet werden, z.B. Anführungszeichen.
Zur Stringkonkatenation wird '+' verwendet, der Operator '*' dient
zum Vervielfachen einer Zeichenkette.
Beispiele:
>>> myString = "Test\nThis should be line 2\tand some space"
>>> print myString
Test
This should be line 2 and some space
>>> myString = 'Man sieht:\ndoppelte " müssen nicht mit einem
\\ maskiert werden,\nwenn der String in einfachen \' steht.'
>>> print myString
Man sieht:
doppelte " müssen nicht mit einem \ maskiert werden,
wenn der String in einfachen ' steht.
>>> myString = """Das ist ein
mehrzeiliger String ohne \\n"""
>>> print myString
Das ist ein
mehrzeiliger String ohne \n
>>> myString = "Pyt" + "hon"
>>> print myString
Python
>>> print (myString + ' ')*3
Python Python Python
List
Eine Python-Liste entspricht in etwa einem Array in anderen Sprachen, nur
daß Objekte beliebigen Typs darin gespeichert werden können.
Der Typ 'list' ist zwar in keiner Klasse definiert, Listen
sind jedoch als Objekte zu betrachten. Da Listen nachträglich änderbar
sind, gibt es für diesen Typ einige vordefinierte Zugriffsmethoden
wie z.B. append (Element(e) an die Liste anhängen), insert
(Element(e) einfügen), sort (Liste sortieren, wobei man auch
eine Sortierfunktion angeben kann), index(elem) (liefert das erste
Vorkommen des Elements)
Die Syntax einer Liste sieht so aus: [ elem1, elem2, ... , elemN
], die leere Liste ist daher [].
Beispiel:
>>> l = ["c", "b", "a", 5]
>>> l.sort() # Standardsortieralgorithmus
>>> l
# Liste ausgeben
[5, 'a', 'b', 'c']
>>> l.index('b') # wo ist 'b' jetzt?
2
Tuple
Tupel bestehen aus mehreren Elementen, die durch Komma getrennt sind und
von runden Klammern eingeschlossen sind. Im Gegensatz zu Listen sind Tupel
nicht nachträglich modifizierbar, ohne daß ein neues Objekt
erzeugt wird.
Die Tupeldefinition sieht analog zu Listendefinition aus, nur daß
die (runden) Klammern auch weggelassen werden können. Bei 0- und einelementigen
Tupeln (Singletons) müssen aber besondere Regeln beachtet werden.
Beispiel:
>>> tuple = 4, 5, 6 # Tupel mit/ohne Klammern deklarieren
>>> sameTuple = (4, 5, 6)
>>> print tuple, sameTuple
(4, 5, 6) (4, 5, 6)
>>> emptyTuple = () # leeres Tupel erzeugen
>>> singleton = "a", # Das Komma darf nicht weggelassen
# werden, sonst ist es kein Tupel
>>> print emptyTuple, singleton
() ('a',)
Wie man schon im Beispiel sieht, können mit Beistrich getrennte
Werte automatisch in ein Tupel gepackt werden. Python unterstützt
auch die andere Richtung, das sogenannte sequence unpacking. Dabei
weist man mehreren mit Kommata getrennten Variablen ein Tupel (es funktioniert
auch für andere Sequenztypen) passender Länge zu, das vom Interpreter
automatisch ausgepackt wird.
Beispiel:
>>> x, y, z = tuple
>>> print x, y, z
4 5 6
Dictionary
Dictionaries sind Listen von Schlüssel-Wert-Kombinationen. Die Schlüssel
dienen dabei als eindeutiger Index, unter dem der gespeicherte Wert gefunden
werden kann. Schlüssel müssen einen nicht modifizierbaren Typ
(Integer, String, Tuple) haben und dürfen
auch keine veränderbaren Objekte enthalten (z.B. Liste innerhalb eines
Tupels). Die Werte selbst können jeden beliebigen Typ haben.
Ein Dictionary wird erzeugt, indem man Paare des Aussehens key:value
in geschweifte Klammern einschließt. Auf ein Element kann über
seinen Schlüssel zugegriffen werden. Um zu erfahren, ob ein Schlüssel
im Dictionary existiert, verwendet man die has_key(key) Methode
von Dictionary. Die Funktion keys() liefert eine Liste aller Schlüssel
zurück.
Die Einträge im Dictionary werden übrigens nicht automatisch
sortiert, man muß dafür die sort()-Funktion verwenden.
Beispiel:
>>> vorwahl = {"A":"0043", "D":"0049"}
>>> vorwahl["CH"] = "0041" # neuer Eintrag wird erzeugt
>>> print vorwahl
{'CH': '0041', 'D': '0049', 'A': '0043'}
>>> del vorwahl["CH"] # Eintrag löschen
>>> vorwahl.has_key("CH") # Eintrag abfragen
0
# -> nicht im Dictionary
Boolesche Ausdrücke
Wie in C gelten alle Booleschen Ausdrücke, die '0' ergeben, als 'false',
alle anderen hingegen als 'true'. Als '0' gelten aber noch zusätzlich:
-
die leere Liste []
-
der leere String ""
-
das leere Tupel ()
-
das leere Dictionary {}
-
None, was Null in C entspricht
Das heißt, alle leeren Sequenzen (mit len(seq) == 0) werden
als 'false' ausgewertet, und nichtleere Sequenzen ergeben daher 'true'.
Typtest, Typumwandlung
Gerade wegen der dynamischen Typisierung sind natürlich Mittel zum
Herausfinden des Typs von Objekten eine große Hilfe.
In Python erhält man mit type(obj) dessen aktuellen Typ
zurück, was z.B. zu Vergleichen genutzt werden kann.
Beispiel:
...
if type(l) == type([]): # Typtest
print l
# Liste verwenden
else:
print "Error: List expected"
...
Dieser Test ist beispielsweise dann nötig, wenn obiger Code in
einer Funktion steht, der l als Parameter übergeben wurde,
da der Funktionsprogrammierer in diesem Fall nicht wissen kann, wie l
tatsächlich aussehen wird.
Zum Umwandeln eines Typs verwendet man die in C++ übliche Schreibweise
(targetType)(sourceExpr).
Sollte die Umwandlung fehlschlagen, erhält man einen ValueError.
Beispiel:
>>> str = "3.14159"
>>> f = (float)(str) # Typ konvertieren
>>> print f, 1/f # Das Ergebnis verwenden
3.14159 0.318310155049