2  Datentypen

Objekte, die Daten speichern, haben einen Datentyp. Der Datentyp gibt an, wie die gespeicherten Werte von Python interpretiert werden sollen. Beispielsweise kann der Wert “1” in Python ein Zeichen, eine Ganzzahl, einen Wahrheitswert, den Monat Januar, den Wochentag Dienstag oder die Ausprägung einer kategorialen Variablen repräsentieren.

In diesem Abschnitt werden die für die Datenanalyse wichtigsten Datentypen vorgestellt.

2.1 Zahlen

Zu den Zahlen gehören Ganzzahlen, boolsche Werte (Wahrheitswerte), Gleitkommazahlen sowie komplexe Zahlen (die hier nicht näher vorgestellt werden).

Ganzzahlen

Ganzzahlen werden standardmäßig im Dezimalsystem eingegeben und können positiv oder negativ sein.

print(12, -8)
12 -8

Darüber hinaus können Ganzzahlen auch in anderen Basen angegeben werden:

  • Dualsystem: Ziffern 0 und 1 mit dem Präfix 0b
print(0b1000, "plus", 0b0000, "plus", 0b0010, \
      "plus", 0b0001, "ist", 0b1011)
8 plus 0 plus 2 plus 1 ist 11
  • Oktalsystem: Ziffern 0 bis 7 mit dem Präfix 0o
print(0o7000, "plus", 0o0700, "plus", 0o0020, \
      "plus", 0o0000, "ist", 0o7720)
3584 plus 448 plus 16 plus 0 ist 4048
  • Hexadezimalsystem: Ziffern 0 bis F mit dem Präfix 0x
print(0xF000, "plus", 0x0200, "plus", 0x00A0, \
      "plus", 0x0001, "ist", 0xF2A1)
61440 plus 512 plus 160 plus 1 ist 62113

Gleitkommazahlen

Gleitkommazahlen werden entweder mit dem Dezimaltrennzeichen . oder in Exponentialschreibweise angegeben. Gleitkommazahlen haben den Typ float.

print(120.6, 1206e-1, 12060e-2, "\n")

print("Beim Lottogewinn in Exponentialschreibeweise zählt das Vorzeichen.")
print(1e-3, "oder", 1e+3)
120.6 120.6 120.6 

Beim Lottogewinn in Exponentialschreibeweise zählt das Vorzeichen.
0.001 oder 1000.0

Da Computer im Binärsystem arbeiten, können Dezimalzahlen nicht exakt gespeichert werden. Beispielsweise ist die Division von 1 durch 10 dezimal gleich 0,1. Binär ist 12 durch 10102 aber ein periodischer Bruch: \[ \frac{1_2}{1010_2} ~ {=} ~ 0,000\overline{1100}_2 \]

Dezimalzahlen müssen deshalb als Bruch zweier Ganzzahlen approximiert werden (Der Binärbruch, der 0.1 annähert, ist in Dezimalschreibweise 3602879701896397 / 255). Dadurch kommt es vor, dass mehrere Gleitkommazahlen durch die selbe Binärapproximation repräsentiert werden. Python gibt zwar die jeweils kürzeste Dezimalzahl aus, da Berechnungen aber binär durchgeführt werden, kann sich bei Berechnungen die nächste Binärapproximation und damit die zugehörige kürzeste Dezimalzahl ändern (weitere Informationen in der Python Dokumentation).

print(0.1) # Die kürzeste Dezimalzahl zur Binärapproximation
print(format(0.1, '.17g')) # Die nächstlängere Dezimalzahl zur selben Binärapproximation
print(0.3 - 0.2) # binär gerechnet, ändert sich die Binärapproximation
0.1
0.10000000000000001
0.09999999999999998

In der praktischen Arbeit mit Python kommen deshalb gelegentlich auf den ersten Blick ungewöhnlich wirkende Ergebnisse vor.

print(0.1 + 0.2)
print(0.01 + 0.02)
print(0.001 + 0.002)
print(0.0001 + 0.0002)
print(0.00001 + 0.00002)
0.30000000000000004
0.03
0.003
0.00030000000000000003
3.0000000000000004e-05

2.2 Arithmetische Operatoren

Mit arithmetischen Operatoren können die Grundrechenarten verwendet werden. Das Ergebnis ist meist vom Typ float, außer, wenn beide Operanden vom Typ int sind und das Ergebnis als ganze Zahl darstellbar ist.

Operator Beschreibung
+, - Addition / Subtraktion
*, / Multiplikation / Division
//, % Ganzzahlige Division / Rest
** Potenzieren

 

Werden mehrere Operatoren kombiniert, so muss deren Reihenfolge beachtet bzw. durch die Verwendung von Klammern (1 + 2) * 3 hergestellt werden. Es gelten die gleichen Regeln wie beim schriftlichen Rechen. Die vollständige Übersicht der Reihenfolge der Ausführung ist in der Pythondokumentation aufgeführt. Für die arithmethischen Operatoren gilt folgende, absteigende Reihenfolge.

Operator
**
* , / , // , %
+ , -

Bei gleichrangigen Operationen werden diese von links nach rechts ausgeführt.

2.3 Aufgaben Zahlen

Lösen Sie die folgenden Aufgaben mit Python.

  1. 4 + 2 * 4 = ?

  2. 2 hoch 12 = ?

  3. Was ist der Rest aus 315 geteilt durch 4?

  4. 𝟣 + 𝟤6 / 𝟧 = ?

  5. Welche Dezimalzahl ist 111111010012 ?

  6. 111111010012 / 1012 = ?

  7. Welcher Kapitalertrag ist größer, wenn 1000 Euro angelegt werden?

    1. 20 Jahre Anlagedauer mit 3 Prozent jährlicher Rendite

    2. 30 Jahre Anlagedauer mit 2 Prozent jährlicher Rendite

Die Musterlösung kann Marc machen.

2.4 Boolsche Werte

Die boolschen Werte True und False sind das Ergebnis logischer Abfragen, die wir später genauer kennenlernen. Sie nehmen auch die Werte 1 und 0 an und gehören in Python deshalb zu den Zahlen.

print("Ist 10 größer als 9?", 10 > 9)
print("Ist 11 kleiner als 10?", 11 < 10)
print("Ist 10 genau 10.0?", 10 == 10.0, "\n")

print("True und False können mit + addiert werden:", True + False)
print("... und mit * multipliziert werden:", True * False, "\n")
Ist 10 größer als 9? True
Ist 11 kleiner als 10? False
Ist 10 genau 10.0? True 

True und False können mit + addiert werden: 1
... und mit * multipliziert werden: 0 

Die Multiplikation von Wahrheitswerten ist nützlich, um mehrere logische Abfragen zu einem logischen UND zu kombinieren:

print("Ist 10 > 9 UND 10 > 8?", (10 > 9) * (10 > 8))
Ist 10 > 9 UND 10 > 8? 1

Die Funktion bool() gibt den Wahrheitswert eines Werts zurück.

print("Ist 10 > 9 UND > 8?", bool((10 > 9) * (10 > 8)))
Ist 10 > 9 UND > 8? True

Die meisten Werte in Python haben den Wahrheitswert True.

print(bool(1), bool(2), bool(2.4))
print(bool('a'), bool('b'), bool('ab'))
True True True
True True True

Neben False und 0 haben leere und nicht existierende Werte oder Objekte den Wahrheitswert False.

print(bool(False), bool(0))
print(bool("")) # eine leere Zeichenfolge
print(bool([])) # eine leere Liste
print(bool(())) # eine leeres Tupel
print(bool({})) # ein leeres Dictionary
print(bool(None)) # None deklariert einen nicht existenten Wert
False False
False
False
False
False
False

Die Sammeltypen Liste, Tupel und Dictionary lernen wir in den folgenden Kapiteln kennen. Boolsche Werte können die Ausführung von Programmcode steuern, indem sie wie an und aus wirken. So kann Programmcode mit einer if-Anweisung nur dann ausgeführt werden, wenn ein Sammeltyp auch Werte enthält.

meine_Liste = ['Äpfel', 'Butter']
if meine_Liste:
    print(f"Wir müssen {meine_Liste} einkaufen.")

meine_Liste = [] # eine leere Liste
if meine_Liste:
    print(f"Wir müssen {meine_Liste} einkaufen.")
Wir müssen ['Äpfel', 'Butter'] einkaufen.

2.5 Logische Operatoren

Zu den logischen Operatoren gehören die logischen Verknüpfungen and, or und not. Darüber hinaus können auch vergleichende Operatoren wie >, >= oder == verwendet werden. Das Ergebnis dieser Operationen ist vom Typ bool. Die Operatoren werden in folgender Reihenfolge ausgeführt. Gleichrangige Operatoren werden von links nach rechts ausgeführt.

Operator Beschreibung
& bitweises UND
^ bitweises XOR
| bitweises ODER
<, <=, >, >=, !=, == kleiner / kleiner gleich / größer als / größer gleich / ungleich / gleich
not logisches NICHT
and logisches UND
or logisches ODER
Hinweis 2.1: Bitweise Operatoren

Besondere Vorsicht ist mit den bitweisen Operatoren geboten. Diese vergleichen Zahlen nicht als Ganzes, sondern stellenweise (im Binärsystem). Zu beachten ist, dass die bitweisen Operatoren Ausführungspriorität vor Vergleichsoperationen haben.

print(10 > 5 and 10 > 6)
print(10 > 5 & 10 > 6)
print(5 & 10)
print(10 > False > 6)
print((10 > 5) & (10 > 6))
True
False
0
False
True
Tipp

Im Allgemeinen werden die bitweisen Operatoren für die Datenanalyse nicht benötigt. Vermeiden Sie unnötige Fehler: Vermeiden Sie die bitweisen Operatoren &, ^ und |.

Die Operatoren &, ^ und | haben jedoch für Mengen (die wir später kennenlernen werden) eine andere Bedeutung. Auch in anderen Modulen kommt den Operatoren syntaktisch eine andere Bedeutung zu, bspw. im Paket Pandas bei der Übergabe mehrerer Slicing-Bedingungen df = df[(Bedingung1) & (Bedingung2) | (Bedingung3)].

2.6 Aufgaben boolsche Werte

Lösen Sie die Aufgaben mit Python.

  1. Ist das Verhältnis aus 44 zu 4.5 größer als 10?
  2. Ist es wahr, dass 4.5 größer als 4 aber kleiner als 5 ist?
  3. Ist 2 hoch 10 gleich 1024?
  4. Sind die Zahlen 3, 4 und 5 ganzzahlig durch 2 teilbar ODER ungleich 10?
  5. Prüfen Sie, ob eine Person den Vollpreis bezahlen muss, wenn Sie Ihr Alter angibt.
    Kinder unter 14 Jahren fahren kostenlos, Jugendliche zwischen 14 und 18 Jahren und Senior:innen ab 65 Jahren erhalten einen Rabatt.

Die Musterlösung kann Marc machen

2.7 Zeichenfolgen

Zeichenfolgen (Englisch string) werden in Python in einfache oder doppelte Anführungszeichen gesetzt.

print('eine Zeichenfolge')
print("noch eine Zeichenfolge")
eine Zeichenfolge
noch eine Zeichenfolge

Innerhalb einer Zeichenfolge können einfache oder doppelte Anführungszeichen verwendet werden, solange diese nicht den die Zeichenfolge umschließenden Anführungszeichen entsprechen.

print('A sophisticated heap beam, which we call a "LASER".')
print("I've turned the moon into what I like to call a 'Death Star'.")
A sophisticated heap beam, which we call a "LASER".
I've turned the moon into what I like to call a 'Death Star'.

Das Steuerzeichen \ (oder Fluchtzeichen, escape character) erlaubt es, bestimmte Sondernzeichen zu verwenden.

print("Das Steuerzeichen \\ ermöglicht die gleichen \"Anführungszeichen\" in der Ausgabe von print.")
print("Erst ein\tTabstopp, dann eine\nneue Zeile.")
Das Steuerzeichen \ ermöglicht die gleichen "Anführungszeichen" in der Ausgabe von print.
Erst ein    Tabstopp, dann eine
neue Zeile.

Ein vorangestelltes r bewirkt, dass das Steuerzeichen \ nicht verarbeitet wird (raw string literal). Dies ist beispielsweise bei der Arbeit mit Dateipfaden praktisch.

print("Die Daten liegen unter: C:\tolle_daten\nordpol\weihnachtsmann")
print(r"Die Daten liegen unter: C:\tolle_daten\nordpol\weihnachtsmann")
Die Daten liegen unter: C:  olle_daten
ordpol\weihnachtsmann
Die Daten liegen unter: C:\tolle_daten\nordpol\weihnachtsmann

2.8 Operationen mit Zeichenfolgen

Einige Operatoren funktionieren auch mit Daten vom Typ string.

# string + string
print('a' + 'b')

# string + Zahl
print(15 * 'a')

# logische Operatoren
print('a' < 'b', 'a' >= 'b', 'a' != 'b')
print('a' or 'b', 'a' and 'b')
ab
aaaaaaaaaaaaaaa
True False True
a b

2.9 Aufgaben Zeichenfolgen

Lösen Sie die Aufgaben mit Python.

  1. Was passiert, wenn Sie die Zeichenfolge “Python” mit ” für Anfänger” addieren?
  2. Erzeugen Sie eine Zeichenfolge, die 10 mal die Zeichenfolge “tick tack” enthält.
  3. Welche Zeichenfolge ist kleiner, “Aachen” oder “Bern”. Warum ist das so, wie werden Zeichenfolgen verglichen?
  4. Geben Sie den Dateipfad aus: “~\home\tobi\neue_daten”

Die Musterlösung kann Marc machen.

2.10 Variablen

Variablen sind Platzhalter bzw. Referenzen auf Daten. Die Zuweisung wird durch den Zuweisungsoperator = dargestellt. Der Name einer Variablen darf nur aus Buchstaben, Zahlen und Unterstrichen bestehen. Dabei darf das erste Zeichen keine Zahl sein.

var_1 = 'ABC'
var_2 = 26
var_3 = True

print("Das", var_1, "hat", var_2, "Buchstaben. Das ist", var_3)
Das ABC hat 26 Buchstaben. Das ist True

Variablen müssen in Python nicht initialisiert werden. Der Datentyp der Variablen wird durch die Zuweisung eines entsprechenden Werts festgelegt.

print("Die Variable var_1 hat den Typ", type(var_1))
print("Die Variable var_2 hat den Typ", type(var_2))
print("Die Variable var_3 hat den Typ", type(var_3))
Die Variable var_1 hat den Typ <class 'str'>
Die Variable var_2 hat den Typ <class 'int'>
Die Variable var_3 hat den Typ <class 'bool'>

Der Datentyp einer Variable ändert sich, wenn ihr ein neuer Wert eines anderen Datentyps zugewiesen wird.

var_1 = 100
print("Die Variable var_1 hat den Typ", type(var_1))
Die Variable var_1 hat den Typ <class 'int'>

Ebenso kann sich der Datentyp einer Variable ändern, um das Ergebnis einer Operation aufnehmen zu können. In diesem Beispiel kann das Ergebnis nicht in Form einer Ganzzahl gespeichert werden. Python weist dem Objekt var_1 deshalb den Datentyp ‘float’ zu.

var_1 = var_1 / 11
print("Die Variable var_1 hat den Typ", type(var_1))
Die Variable var_1 hat den Typ <class 'float'>

Python enthält Funktionen, um den Datentyp einer Variablen zu bestimmen und umzuwandeln. Die Funktion type() wurde in den Code-Beispielen bereits benutzt, um den Datentyp (bzw. die Klasse) von Objekten zu bestimmen. Die Umwandlung des Datentyps zeigt der folgende Code-Block.

a = 67 
print(a, type(a))

b = a + 1.8
print(b, type(b), "\n")

print(f"Beachten Sie das Abschneiden der Nachkommastelle:\nUmwandlung in Ganzzahlen mit int(): {( a := int(a) ), (b := int(b) )}\n")

print(f"Umwandlung in ASCII-Zeichen mit chr(): {( a := chr(a) ), ( b := chr(b) )}\n")

print(f"Umwandlung in eine ASCII-Zahl mit ord(): {( a := ord(a) ), ( b := ord(b) )}\n")

print(f"Umwandlung in Fließkommazahlen mit float(): {( a := float(a) ), ( b := float(b) )}\n")

print(f"Umwandlung in Zeichen mit str(): {( a := str(a) ), ( b:= str(b) )}\n")

print(f"Umwandlung in Wahrheitswerte mit bool(): {bool(a), bool(b)}")
67 <class 'int'>
68.8 <class 'float'> 

Beachten Sie das Abschneiden der Nachkommastelle:
Umwandlung in Ganzzahlen mit int(): (67, 68)

Umwandlung in ASCII-Zeichen mit chr(): ('C', 'D')

Umwandlung in eine ASCII-Zahl mit ord(): (67, 68)

Umwandlung in Fließkommazahlen mit float(): (67.0, 68.0)

Umwandlung in Zeichen mit str(): ('67.0', '68.0')

Umwandlung in Wahrheitswerte mit bool(): (True, True)

Weitere Zuweisungsoperatoren

In dem obenstehenden Code-Block wurde der sogenannte Walross-Operator := verwendet. Dieser erlaubt es, Zuweisungen innerhalb eines Ausdrucks (hier innerhalb der Funktion print()) vorzunehmen. Python kennt eine ganze Reihe weiterer Zuweisungsoperatoren (weitere Operatoren siehe Python-Dokumentation oder übersichtlicher hier).

Operator entspricht der Zuweisung
a += 2 a = a + 2
a -= 2 a = a - 2
a *= 2 a = a * 2
a /= 2 a = a / 2
a %= 2 a = a % 2
a //= 2 a = a // 2
a **= 2 a = a ** 2
Tipp 2.4: Lesbare Zuweisungen

Die in der Tabelle gezeigten Zuweisungsoperatoren sind für jemanden, der*die Ihren Code liest, gut zu lesen und nachzuvollziehen, da Zuweisungen immer am Beginn einer Zeile, also ganz links, stehen.

Dagegen kann der Walross-Operator an einer beliebigen Stelle in Ihrem Code stehen. Das mag für Sie beim Schreiben ein Vorteil sein, der Lesbarkeit ist das aber abträglich. Wenn Sie den Walross-Operator verwenden, achten Sie deshalb auf die Nachvollziehbarkeit Ihres Codes.

Benennung von Variablen

Für die Benennung von Variablen gibt es (meist) nur wenige Vorgaben. Trotzdem ist es besser, einen langen, aber ausführlichen Variablennamen zu vergeben, als einen kurzen, der sich schnell schreiben lässt. Denn Programmcode wird deutlich häufiger gelesen als geschrieben. Können Sie sich erinnern? Welcher Wert ist in der Variablen Var_3 gespeichert, und welche Werte sind in variable1 und a gespeichert? Es reicht schon, wenn Sie sich an den richtigen Datentyp erinnern können.

Falls Sie sich nicht erinnern können, dann ist dieses Beispiel gelungen: Die Namensgebung dieser Variablen ist alles andere als gut. Die Auflösung steht im folgenden Aufklapper.

print(var_3, type(var_3))
print(variable1, type(variable1))
print(a, type(a))
True <class 'bool'>
15 <class 'int'>
67.0 <class 'str'>

Deshalb empfiehlt es sich “sprechende”, das heißt selbsterklärende, Variablennamen zu vergeben. Unter selbsterklärenden Variablennamen versteht sich, dass der Variablenname den Inhalt der Variable beschreibt. Wird bspw. in einer Variable der Studienabschluss gespeichert, so kann diese mit academic_degree oder studienabschluss bezeichnet werden. Werden Daten aus verschiedenen Jahren verarbeitet, kann das Jahr zu besseren Unterscheidbarkeit in den Variablennamen einfließen, etwa: academic_degree_2023 oder studienabschluss2024. Dies verbessert die Lesbarkeit des Codes und vereinfacht die Benutzung der Variable. Mehr Informationen finden sich in diesem Wikipedia Abschnitt.

Hinweis 2.2: Schlüsselwörter und Funktionsnamen

In Python reservierte Schlüsselwörter und Funktionsnamen sind ungeeignete Variablennamen. Während Python die Wertzuweisung zu Schlüsselwörtern wie True oder break mit einem Syntaxfehler quittiert, lassen sich Funktionsnamen neue Werte zuweisen, beispielsweise mit print = 6. Wenn Sie die Funktion print dann aufrufen, funktioniert diese natürlich nicht mehr. In diesem Fall müssen Sie die Zuweisung aus dem Skript entfernen und Python neu starten.

Folgende Schlüsselwörter gibt es in Python:

and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield
await      else       import     pass       True
break      except     in         raise      class
False      finally    is         return     None

2.11 Aufgaben Variablen

  1. Schreiben Sie ein Skript, welches eine gegebene Zeit 𝗍 in Sekunden in die Anzahl Tage, Stunden, Minuten und Sekunden aufteilt und diese Aufteilung ausgibt.
    Berechnen Sie die Aufteilung für folgende Zeiten:

    1. 79222 s

    2. 90061 s

    3. 300000 s

  2. Die Position eines Fahrzeugs zur Zeit \(t\), welches konstant mit der Beschleunigung \(a\) beschleunigt, ist gegeben durch:

\[ x(t) = x_0 + v_0 \cdot t + \frac{1}{2} \cdot a t^2 \]

Dabei ist \(x_0\) die Anfangsposition und \(v_0\) die Anfangsgeschwindigkeit. Erstellen Sie Variablen für \(x_0\), \(v_0\) und \(a\) und weisen Sie ihnen Werte zu. Da die Variablen nur Werte, aber keine Einheiten abbilden, überlegen Sie sich die ggf. notwendigen Umrechnungen. Folgende Werte können sie als Beispiel verwenden:

\[ x_0 = 10 \, km \,\,\,v_0 = 50 \frac{km}{h} \,\,\,a = 0.1 \frac{m}{s^2} \]

Erzeugen Sie eine Variable für den Zeitpunkt \(t\), z. B.: \(t = 10 \, min\). Berechnen Sie mit obiger Gleichung und mit Hilfe der Variablen die Position \(x(t)\). Geben Sie nicht nur den Wert von \(x(t)\) in Kilometer aus, sondern betten ihn in einen ganzen Antwortsatz (einschließlich Einheiten) ein.

Die Musterlösung kann Marc machen.

(Arnold 2023a, 2023b)

Arnold, Simone. 2023a. „Datenanalyse mit Python. Datentypen und Grundlagen.“ Fachhochschule Dortmund.
———. 2023b. „Datenanalyse mit Python. Funktionen Module Dateien.“ Fachhochschule Dortmund.