Variablennamen
Ein Variablenname kann grundsätzlich beliebig lang sein, unterliegt aber gewissen Bedingungen:
import keyword # alle vergebenen Namen print(keyword.kwlist)
Der Typ None
Eine Variable kann nicht deklariert werden, ohne dass ihr ein Wert (Typ) zugewiesen wird. Ist dies der Fall, bekommt sie den "Typ" undefined zugewiesen und verursacht einen Fehler:
var_0 # NICHT definiert! -> Fehler!! var_1 = None # definiert, aber ohne sinnvollen Typ/Wert var_2 = 2 print("Ausgabe der Typen: ", type(var_1), type(var_2))
Der Typ None
entspricht einer Konstanten und kann für Abfragen benutzt werden, um festzustellen, ob einer
Variablen ein neuer Wert zugewiesen wurde:
var_1 = "hat einen Wert" if var_1 is None: print('var_1 hat keinen Wert.') else: print('Der Wert von var_1 ist ', var_1) print('und der Typ ist ', type(var_1))
var_1 = None
!
Wenn Sie Informationen zum if-Konstrukt wüschen, so gehen Sie zur zweiten Kurseinheit.
Der Typ Bool
Boolesche Variablen können die Werte False oder True annehmen, wobei
Python die Zahl 1, beziehungsweise die Zahl 0 als True, beziehungsweise False, interpretiert. Dadurch
ist True
+ True eine zulässige Operation und ergibt 2. Grundsätzlich ist jede Ganzzahl größer als 0 True.
Dieser formale Wahrheitswert kann mithilfe der Standardfunktion
bool()
ermittelt werden.
var_1 = 177 var_2 = 13 print(bool(var_1 + var_2))
bool(var_1 * var_2)
,
bool(var_1/var_2)
und bool(var_1//var_2)
ergibt!
Der Typ int –- Ganze Zahlen
Ganzzahlige Werte werden in Python durch den Datentyp int repräsentiert. Eine frühere Unterscheidung in int und longint existiert nicht mehr. Die Größe eines int war in Python 2 auf 32 Bit begrenzt. Ganzzahlen waren daher im Bereich von -2.147.483.648 bis 2.147.483.647 möglich. Ein longint erlaubte den Bereich -9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807. In Python 3 ist der lange Datentyp nicht mehr vorhanden und außerdem ein aktualisiertes int, welches eine beliebige Größe haben kann! Dies ist in fast allen anderen Programmiersprachen nicht möglich. Trotzdem kann es zu langen Rechenzeiten kommen, wenn man mit "bombastischen" Zahlen rechnet. Wir zeigen das am Beispiel der Berechnung einer Fakultät: n!=1*2*3*4*...*n
Um die Anzahl an Ziffern einer Ganzzahl zu bestimmen, kann diese zuerst
mit der Standardfunktion str()
(string) in eine Zeichenkette
umgewandelt werden. Von dieser lässt sich anschließend mit der Standardfunktion len()
(length)
die Länge (Anzahl der Zeichen) bestimmt werden. Beides kann auch in einem Schritt erfolgen:
k = 1 # Startwert maxN = 1000 for i in range(1, maxN): # Bereich 1,2,3,...maxN-1 k = k * i # n-1*n #print(k) # Die Zahl n! print(len(str(k))) # Anzahl Ziffern
maxN = 10000
längere Rechenzeiten ergeben!Für Fortgeschrittene: Testen Sie, ob es ein n! mit genau 12345 Stellen gibt.
Lösung siehe hier.
Wird in obigem Beispiel die Maximalzahl erst durch eine Eingabe über input()
vorgegeben,
so ist zu beachten, dass sie dann formal als Zeichenkette (String) und nicht als Zahl existiert; es können
nur Zeichenketten eingelsen werden!
Mit der Standardfunktion int()
ist dann aber eine Konvertierung in eine
Ganzzahl möglich. Das folgende Beispiel kann nur auf dem eigenen Rechner ausgeführt werden, da die meisten
Online-Compiler keine interaktiven Aktionen erlauben.
k = 1 # Startwert #maxN = input("Max= ") # auf der Webseite nicht möglich maxN = 100 for i in range(1, int(maxN)): # Bereich 1,2,3,...maxN-1 k = k * i # n-1*n #print(k) # Die Zahl n! print(len(str(k))) # Anzahl Ziffern
Standardmäßig werden Ganzzahlen im üblichen Zehnersystem ausgegeben. Es ist aber auch eine einfache Wandlung der Zahlen in binärer (Basis 2), oktaler (Basis 8)oder hexadezimaler (Basis 16) Darstellung möglich, wie sie vielfach in Programmen für Interna von Computern benötigt werden. Die entsprechenden Standardfunktionen zeigt das folgende Beispiel, wobei zu beachten ist, dass wegen des Zeichenpräfixes zur Festlegung der Basis die Ausgaben dann Zeichenketten sind.:
Zahl = 65535 print(Zahl) print(hex(Zahl)) print(oct(Zahl)) print(bin(Zahl))
0x steht für Hexadezimal, 0o für Oktal und 0b für Binär. Eine Rückwandlung in eine Dezimalzahl ist dann wieder
über die Standardfunktion int()
möglich. Die Angabe des jeweiligen Präfixes kann entfallen, da
zwingend als zweiter Parameter die Basis angegeben werden muss:
Zahl = 65535 Hex = hex(Zahl) Oct = oct(Zahl) Bin = bin(Zahl) print(Hex, int(Hex,base=16)) print(Oct, int(Oct,base=8)) print(Bin, int(Bin,base=2)) print(int('0xFFFF',base=16))# Eingabe als Zeichenkette print(int('FFFF',base=16)) # " " "
Weitere Standardfunktionen für Ganzzahlen (Integer) sind min()
und max()
, welche
von einer Zahlenliste den kleinsten, beziehungsweise größten Wert zurückgeben, sowie die Funktion abs()
,
welche den Absolutwert (Betrag) einer Zahl zurückgibt. Alle drei Funktionen können auch für Gleitkommazahlen
(Float)
angewendet werden:
print(min(1, 4, -3, 15, -3.1)) print(max(1, 4, -3, 15, -3.1)) print(abs(min(1, 4, -3, 15, -3.1)))
Der Typ float –- Gleitkommazahlen (floating numbers)
Dezimalzahlen werden in vielen Programmiersprachen, so auch in Python durch den Datentyp float repräsentiert.
Die Nachkommastellen werden dabei – wie im englischen Sprachraum üblich – durch
einen Punkt von dem ganzzahligen Anteil getrennt. Große oder sehr kleine Dezimalzahlen lassen sich in der
Exponentialschreibweise angeben. 1.2e3 steht dann für 1.2*103. Die Ausgabe von Gleitkommazahlen ist dabei
nicht ganz konsequent, wie man im folgenden Beispiel sieht. Mal gibt es die Ausgabe als Gleitkommazahl und mal nicht.
Es existieren die üblichen Rundungsfunktionen wie round()
und int()
, wobei erstere ohne Angabe
eines zweiten Parameters auf die nächste ganze Zahl rundet. Mit dem zweiten Parameter
kann auf n Nachkommastellen gerundet
werden. Mit int()
wird einfach der Nachkommateil abgeschnitten. In anderen Programmiersprachen auch
als trunc
bezeichnet.
print(" 0: ", -1e-1) print(" 1: ", 1/1e12) print(" 2: ", 1/1e-12) print(" 3: ", 1.23e2/1.1e2) print(" 4: ", round(1.23e2/1.1e2)) # nächste ganze Zahl print(" 5: ", round(0.987)) # " " " print(" 6: ", round(-0.987)) # " " " print(" 7: ", round(1.23e2/1.1e2, 4)) # auf vier Nachkommastellen runden print(" 8: ", int(1.23e2/1.1e2)) # Nachkommastellen abschneiden, nächste, kleinere ganze Zahl print(" 9: ", int(0.987)) # " " print("10: ", int(-0.987)) # " "
Der Typ complex –- Komplexe Zahlen
Komplexe Zahlen bestehen aus einem Realteil und einem Imaginärteil. Der Imaginärteil 1
besteht aus einer reellen Zahl, die mit der imaginären Einheit i (der Wurzel aus -1) multipliziert wird.
Zur Vermeidung von Missverständnissen benutzt Python für die imaginäre Einheit das j, um Probleme mit der
Elektrotechnik zu vermeiden, wo das i bereits für den Strom vergeben ist und man daher dort ebenfalls j benutzt.
Weiterhin muss das j nach der Zahl erscheinen.
Komplexe Zahlen können können über die Standardfunktion complex()
oder direkt definiert werden:
c1 = 1 + 2j c2 = complex(1,2) c3 = -1.1e2 - 0.1e1j print(c1,c2,c3)
Eine praktische Anwendung zeigt das folgende Beispiel, welches die Mandelbrotmenge in der seinerzeit von Benoit Mandelbrot erstellten Originalausgabe, die im reinen Textmodus erfolgte. Grafische Ausgaben waren nur auf den wenigsten Computern möglich. Man geht von der komplexen Gleichung $z_{n+1}=z_n^2+C$ aus, wobei $z_0=(0+i0)$ der Startwert ist und die komplexe Konstante C den Wert für die aktuellen Startkoordinaten enthält. Vorgegeben ist ein Koordinatensystem mit $-3<x<2.5$ und $-1.5<y<1.5$, welches in 24 Zeilen und 80 Spalten aufgeteilt wird. Wegen der reinen Textausgabe wird oben links begonnen (Zeile 1, Spalte 1, beziehungsweise $x=-3$ und $y=1.5$). Tendiert die Zahlenfolge $z_n$ gegen Null wird für das Koordinatenpaar(Spalte,Zeile) ein X ausgegeben, anderenfalls ein Leerzeichen. Abgebrochen wird die Iteration auch dann, wenn der Ortsvektor länger als rMax ist (aufgrund der Annahme, dass die Folge dann divergiert).
MaxZeilen = 24 MaxSpalten = 80 ReellMin = -3.0 ReellMax = 2.5 ImagMin = -1.5 ImagMax = +1.5 rMax = 50 MaxIter = 26 def iterat(x, y): # (x|y) Startkoordinaten c = complex(x,y) # Konstante k = 0 # Laufvariable z = complex(0,0) # z_0 (startwert der Iteration) while (k < MaxIter) and (abs(z) <= rMax): z = z**2 + c k += 1 # um 1 inkrementieren return k DeltaReell = (ReellMax - ReellMin) / MaxSpalten # dx in Weltkoordinaten DeltaImag = (ImagMax - ImagMin) / MaxZeilen # dy in " " } y = ImagMax while (y >= ImagMin): x = ReellMin while (x <= ReellMax): it = iterat(x,y) if (it >= MaxIter): print('X',end="") else: print(' ',end="") x = x + DeltaReell print() y = y - DeltaImag print()
Interessierte können sich hier die Ausgabe als Grafik ansehen. Das entsprechende Python-Programm ist mandel.py.
Für das Arbeiten mit komplexen Zahlen kann auch das Modul cmath aus der Standardbibliothek sinnvoll sein.
Der Typ str –- Zeichenketten (Strings)
Zeichenketten (Strings) sind eine Folge von beliebigen Zeichen, die wahlweise in 'einfachen' oder "doppelten" Anführungszeichen geschrieben werden. Hintergrundinformationen gibt es hier: https://kunststube.net/encoding/. Ein Computer versteht nur Bits (zwei Zustände). Für Zeichen wurden diese zu einem Byte zusammengefasst (8 Bit -- 256 Zustände). Durch die Internationalisierung (Japan hat alleine ca. 5000 Kanjis) reichte das irgendwann nicht, sodass Kombinationen von Bytes, wie UTF-16 (2 Byte) und UTF-32 (4 Byte) definiert wurden, um möglichst jedes Schriftzeichen, welches auf der Welt existiert, darstellen zu können.
Nahezu jedes Python-Objekt kann
durch die Standardfunktion str(object)
in eine Zeichenkette gewandelt werden. Dies kann beispielsweise für eine
eventuelle Ausgabe mit print()
sinnvoll sein. Besteht eine Zeichenkette nur aus einem einzigen Zeichen,
wird auch von einem char
-Typ gesprochen.
string_1 = "Eine Zeichenkette" string_2 = 'ドイツ' string_3 = "'Zeichen'" string_4 = '"Zeichen"' print(string_1, string_2, string_3, string_4)
Der Rückgabewert von chr(Ganzzahl)
ist
Zeichenketten, die nur aus einem Zeichen bestehen, können auch durch ihre numerische Entsprechung dargestellt werden (Ordinalzahl):
print(ord('@')) print(chr(64)) z = ord('\\')# Backslash maskieren! print(z) print(chr(z)) print(chr(54321))
print(chr(97)) print(chr(65)) print(chr(1200)) x = "".join([chr(0x265a+n) for n in [2,4,3,1,0,3,4,2]])# Figuren print(x + "\n" + chr(0x265f)*8) # Bauern x = "".join([chr(0x2654+n) for n in [2,4,3,1,0,3,4,2]])# Figuren print(x + "\n" + chr(0x2659)*8) # Bauern print() print([chr(0x263f + n) for n in range(9)])# Planetensymbole
Eine Zusammenstellung aller Zeichen mit ihren zugeordneten Zahlen in Hexadezimalform (Basis 16) findet man auf der Unicode-Seite https://www.unicode.org/charts/. Die Basiszeichen für lateinische Zeichen zeigt https://www.unicode.org/charts/PDF/U0000.pdf. Dem Zeichen @ ist demnach die Zahl 0040(16) zugeordnet, was der Dezimalzahl 4*16=64 entspricht. Die Schachfiguren und Planetensymbole findet man auf https://www.unicode.org/charts/PDF/U2600.pdf
Zeichenketten können durch "Addition" miteinander kombiniert werden (concenation). Möchte man eine Zeichenkette beliebiger Länge in mehrfacher Wiederholung, so kann diese mittels * und einer ganzzahligen Zahl vervielfacht werden. Es ist etwas gewöhnungsbedürftig, dass die einfachen Rechenoperationen auch mit Strings möglich sind. Da Zeichenketten in Python unveränderbar sind, können auch nicht einzelne Zeichen ausgetauscht werden. Es muss in jedem Fall eine neue Zeichenkette erzeugt werden, die allerdings den alten Variablennamen erhalten darf.
string_1 = "Eine Zeichenkette" string_2 = 'ドイツ' string_3 = "'Zeichen'" string_4 = '"Zeichen"' print(string_1 + 3*(string_2+" ")) print(string_1+" "+string_3+" "+string_4)
Die Länge (Anzahl Zeichen) einer Zeichenkette kann durch len() bestimmt werden:
str_0 = "私の名前は「Herbert Voß」で、大学で働いています。" print("Der Satz hat ",len(str_0)," Zeichen!")
Sollen Anführungszeichen, einfache oder doppelte, in einem String vorkommen, der durch gleichartige Anführungszeichen begrenzt ist, so muss das Zeichen durch einen vorangestellten Backslash maskiert (escaped) werden.
str_0 = "\"Donald \"" str_1 = '\'...\'' print(str_0 + str_1 + " fehlt mir gerade noch.")
Zur besseren Lesbarkeit von Programmen sollten Code-Zeilen nicht mehr als 80 Zeichen lang sein. Für die Zuweisung von längeren Zeichenketten kann mit einem Backslash am Ende einer Zeile erreicht werden, dass das folgende Zeilenendezeichen ignoriert wird und der BAckslash durch die folgende(n) Zeile(n) ersetzt wird, so dass der String-Variablen eine Zeichenkette ohne Zeilenumbruch zugewiesen wird:
str_0 = 'Also sprach Zarathrusta: \ „Es ist wahr: Wir lieben das Leben, nicht, weil wir ans Leben, sondern ans Lieben gewöhnt sind. \ Es ist immer etwas Wahnsinn in der Liebe. Es ist aber auch immer etwas Vernunft im Wahnsinn.“' print(str_0)
Hinter dem Backslash darf in derselben Zeile kein Kommentarzeichen folgen! Mehrzeilige Zeichenketten können alternativ auch in dreifache Anführungszeichen gesetzt werden. Diese sogenannten „Docstrings“ werden eigentlich verwendet, um längere Code-Abschnitte zu dokumentieren. Man kann sie aber auch für mehzeilge Strings verwenden, wobei das Zeilenendezeichen im Gegensatz zum obigen Beispiel erhalten bleibt und sich somit eine andere Ausgabe ergibt:
str_0 = '''Also sprach Zarathrusta: „Es ist wahr: Wir lieben das Leben, nicht, weil wir ans Leben, sondern ans Lieben gewöhnt sind. Es ist immer etwas Wahnsinn in der Liebe. Es ist aber auch immer etwas Vernunft im Wahnsinn.“ ''' print(str_0)
Folgende Zeichenkombinationen haben eine Sonderbedeutung und unterliegen einer Sonderbehandlung:
Zeichen | Bedeutung |
---|---|
\t | Tabulator |
\n | Newline (Zeilenumbruch) |
\r | Carriage Return |
\\ | Backslash |
\' | Einfaches Anführungszeichen |
\" | Doppeltes Anführungszeichen |
\xnn | Sonderzeichen (ASCII ), repräsentiert durch eine zweistellige Hexadezimalzahl, beispielsweise \xe4 |
\unnnn | Sonderzeichen (16-bit-Unicode), repräsentiert durch eine vierstellige Hexadezimalzahl, beispielsweise \u7fe2 |
Möchte man das Interpretieren der obigen Sonderzeichen unterbinden, kann dies durch ein vorangestelltes r („raw“) geschehen; beispielsweise r'a\tb' oder r"a\nb":
str_0 = 'X\tY' str_r0 = r'X\tY' str_1 = "X\nY" str_r1 = r"X\nY" str_2 = 'X\rY' str_r2 = r'X\rY' str_3 = 'X\\Y' str_r3 = r'X\\Y' str_4 = 'X\'Y' str_r4 = r'X\'Y' str_5 = 'X\"Y' str_r5 = r'X\"Y' str_6 = 'X\xafY' str_r6 = r'X\xafY' str_7 = 'X\uafafY' str_r7 = r'X\uafafY' print(str_0, str_r0) print(str_1, str_r1) print(str_2, str_r2) print(str_3, str_r3) print(str_4, str_r4) print(str_5, str_r5) print(str_6, str_r6) print(str_7, str_r7)
Indizierung von Zeichenketten
Eine Zeichenkette entspricht einem Vektor, auf dessen einzelne Elemente (Zeichen) man mit dem Index-Operator [ ] zugreifen kann. Dabei beginnt die Zählung mit 0 und endet bei n Zeichen bei n-1. Zugriffe auf kleinere Werte als -n oder größere Werte als n-1 führt zu einem Fehler. Dabei ist zu beachten, dass mit dem Index[-1] das letzte Element und mit [-n] das erste Element gemeint ist:
str0 = "Franz von Hahn" print("Element -1: "+str0[-1]) n = len(str0) print("Element -n: "+str0[-n])
str0 = "Hannah" print(str0) for i in range(len(str0)): # 0,1,2,...,n-1 print(i, str0[i]) print() for i in reversed(range(len(str0))): # n-1,n-2,...,2,1,0 print(i, str0[i]) print() for i in range(1,len(str0)+1): # 0,1,2,...,n-1 print(-i, str0[-i]) print()
Anstelle einzelner Zeichen kann auch eine Zeichenfolge (slice) aus der Zeichenkette extrahiert werden, wozu zwei durch Doppelpunkt getrennte Zahlen angegeben werden, die für den Bereich stehen. Der obere Bereich ist dabei jeweils nicht eingeschlossen. Fehlt die erste oder zweite Zahl, so wird jeweils vom Anfang, beziehungsweise Ende ausgegangen. Wird eine dritte, ebenfalls durch einen Doppelpunkt getrennt, angegeben, so kennzeichnet diese die Schrittweite. Bei einem negativen Wert kann von hinten gezählt werden:
str0 = "Hannah" print(str0) for i in range(len(str0)): # 0,1,2,...,n-1 print(i, str0[i:], str0[:i]) # von i, bis i print() for i in range(0,len(str0)-1,2): # 0,2,4,.,n-1 mod 2 print(i, str0[i:i+2]) # i,i+1 print() str1 = "Ein längerer Satz, der sinnlos ist." print(str1[3:28:2]) print(str1[28:3:-2]) print() for i in range(len(str1)): # 0,1,2,...,n-1 print(i, str1[i::2], str1[:i:2]) # von i, bis i print()
String-Funktionen
Wie in allen Programmiersprachen gibt
es auch in Python einige Funktionen, die im Allgemeinen in der Form Zeichenkette.Funktion()
angewendet werden.
Suchen von Teilstrings
Mit dem in-Operator kann geprüft werden, ob eine Zeichenkette in einer anderen Zeichenkette enthalten ist, beziehungsweise wie oft. Für die Häufigkeit kann auch nur ein Intervall berücksichtigt werden:
str0 = "Hannah Montana" if 'an' in str0: print('"an" ist in "'+str0+"\" enthalten") else: print('"an" ist in "'+str0+"\" nicht enthalten") n = str0.count('an') print('"an" ist in "'+str0+"\" genau "+str(n)+"-mal enthalten") n = str0.count('an',5,13) print('"an" ist in "'+str0[5:13]+"\" genau "+str(n)+"-mal enthalten")
Mit str.find()
kann die Position eines Teilstrings innerhalb eines Stringvektors
bestimmt werden. Ist der Teilstring nicht enthalten, so wird -1 zurückgegeben.
Zu beachten ist, dass die Zählung mit Null beginnt. Mit str.rfind()
kann man die Suche von rechts beginnen lassen. Durch weitere Paremeter kann die Suche wieder
auf Teilintervalle beschränt werden:
str0 = "Hannah Montana" n = str0.find('an') if n > -1: print('"an" ist in "'+str0+"\" erstmalig an der Stelle ",n) else: print('"an" ist in "'+str0+"\" nicht enthalten") n = str0.rfind('an') if n > -1: print('"an" ist in "'+str0+"\" letztmalig an der Stelle ",n) else: print('"an" ist in "'+str0+"\" nicht enthalten") n = str0.find('an',10,20) if n > -1: print('"an" ist in "'+str0+"[10:20]\" erstmalig an der Stelle ",n) else: print('"an" ist in "'+str0+"[10:20]\" nicht enthalten")
Interessiert grundsätzlich nur das Ende Strings, beispielsweise bei einem Dateinamen, so kann
die Funktion str.endswith()
genutzt werden, welche einen Boolschen Wert zurückliefert.
Analog dazu existiert auch eine Funktion str.startswith()
:
str0 = "index.html" if str0.endswith('.html'): print(str0, "ist eine html-Datei") else: print(str0, "ist keine html-Datei") if str0.endswith('.php'): print(str0, "ist eine php-Datei") else: print(str0, "ist keine php-Datei") if str0.startswith('index'): print(str0, "ist die standardmäßige index-Datei") else: print(str0, "ist keine index-Datei")
Ersetzen von Teilstrings
Wie bereits erwähnt wurde, sind einmal definierte Zeichenketten
unveränderbar. Daher kann der Index-Operator nicht auf der linken
Seite einer Zuweisung (Gleichheitszeichen) stehen. Es muss daher ein Zwischenschritt
erfolgen, was von der Funktion str.replace()
intern erledigt wird:
str0 = "Hannah Montana" print(str0.replace("Hannah","Hanna")) str0 = str0.replace("Hannah","Johanna") print(str0) str1 = "Hannah Montana".replace("Montana","Idaho") print(str1)
Komfortablere und vor allem komplexere Ersetzungen sind mit Hilfe von regulären Ausdrücken möglich. Man kann auch mit Übersetzungstabellen arbeiten:
str0 = "H%(&=annah)" sonderzeichenB = "-=[]()" # trans_table = str0.maketrans(sonderzeichenB, " " * len(sonderzeichenB)) print(trans_table) # dictionary a->b (a wird b) print() str0 = str0.translate(trans_table) print(str0)
Groß- und Kleinschreibung ändern
Da Groß-/Kleinschreibung für Python signifikant ist, kann die Bedeutung von Zeichenketten nur
dann verglichen werden, wenn sie vorher in KLein- oder Großbuchstaben gewandelt werden.
Mit str.capitalize()
werden sie in die Standardschreibweise mit einem großen Anfangsbuchtsaben
und Rest Kleinbuchstaben gewandelt, wohingegen str.title()
dies für jedes Teilwort einer Zeichenkette macht.
Groß- und Kleinbuchstaben können durch str.swapcase()
vertauscht werden:
str0 = "Hannah" str1 = "hANNah" str2 = "ANNah" if str0.lower() == str1.lower(): print("Die Zeichenketten str0 und str1 bedeuten dasselbe!") if str0.upper() == str1.upper(): print("Die Zeichenketten str0 und str1 bedeuten dasselbe!") if str0.upper() == str2.upper(): print("Die Zeichenketten str0 und str2 bedeuten dasselbe!") else: print("Die Zeichenketten str0 und str2 bedeuten nicht dasselbe!") str3 = str0+" "+str1+" "+str2 print(str3) print(str3.capitalize()) print(str3.title()) print(str3.swapcase())
Leerzeichen am Anfang und Ende entfernen
Mit den Funktionen str.lstrip()
, str.rstrip()
und str.strip()
lassen sich Leerzeichen am Anfang, am Ende oder an beiden Stellen
einer Zeichenkette entfernen;
str0 = " Johnny Mauser " print("|"+str0.lstrip()+"|") print("|"+str0.rstrip()+"|") print("|"+str0.strip()+"|")
Text zentrieren
Die Funktion str.center()
zum Zentrieren einer Zeichenkette innerhalb einer vorgegebenen Stringlänge
ist faktisch nur für eine folgende Ausgabe sinnvoll.
str0 = "Johnny Mauser" print("|"+str0.center(10)+"|") # keine Zentrierung, da Zeichenzahl größer als 10! print("|"+str0.center(20)+"|") print("|"+str0.center(30)+"|") print("|"+str0.center(40)+"|")
Aufteilen und Zusammenfügen von Zeichenketten
Mit der Funktion str.split()
kann eine Zeichenkette in eine Liste von Teilstrings aufgeteilt werden,
um beispielsweise festzustellen, wieviel Wörter ein Text enthält. Standardmäßig wird das Leerzeichen als Trennzeichen
benutzt, es kann über den optionalen Parameter aber jedes andere Zeichen angegeben werden. Die Umkehrung erfolgt mit
separator.join(
, wobei der Separator eine beliebige Zeichenkette sein kann, die als Trennzeichen
zwischen den zusammenzuführenden Elementen benutzt wird.
str0 = """Eine wunderbare Heiterkeit hat meine ganze Seele eingenommen, gleich den süßen Frühlingsmorgen, die ich mit ganzem Herzen genieße. Ich bin allein und freue mich meines Lebens in dieser Gegend, die für solche Seelen geschaffen ist wie die meine. Ich bin so glücklich, mein Bester, so ganz in dem Gefühle von ruhigem Dasein versunken, daß meine Kunst darunter leidet. Ich könnte jetzt nicht zeichnen, nicht einen Strich, und bin nie ein größerer Maler gewesen als in diesen Augenblicken. Wenn das liebe Tal um mich dampft, und die hohe Sonne an der Oberfläche der undurchdringlichen Finsternis meines Waldes ruht, und nur einzelne Strahlen sich in das innere Heiligtum stehlen, ich dann im hohen Grase am fallenden Bache liege, und näher an der Erde tausend mannigfaltige Gräschen mir merkwürdig werden; wenn ich das Wimmeln der kleinen Welt zwischen Halmen, die unzähligen, unergründlichen Gestalten der Würmchen, der Mückchen näher an meinem Herzen fühle, und fühle die Gegenwart des Allmächtigen, der uns nach seinem Bilde schuf, das Wehen des Alliebenden, der uns in ewiger Wonne schwebend trägt und erhält; mein Freund! Wenn's dann um meine Augen dämmert, und die Welt um mich her und der Himmel ganz in meiner Seele ruhn wie die Gestalt einer ... """ Woerter = str0.split() print(Woerter) print("Der Text hat insgesamt ", len(Woerter)-1, " Worter") # -1 wegen ... :-) print(''.join(Woerter)) # Kein Trenner angegeben print(' '.join(Woerter)) # Leerzeichen als Trenner Vektor = "1, 2, 3, 4, 5, 1.234, 1.33e17, 0.12" # komma-separierte Liste strVektor = Vektor.split(",") print(strVektor) print("Der Vektor hat ",len(strVektor)," Elemente") str1 = "" print(str1.join(strVektor)) print(", ".join(strVektor))
Formatierung von Zeichenketten
Bei der formatierten Ausgabe von Strings und Zahlenwerten, die bezogen auf die Ausgabe ebenfalls Zeichenketten darstellen,
kann man eine Notation in Anlehnung an die Programmiersprache C benutzen. Die sogenannten
Platzhalter werden durch ein Prozentzeichen markiert. Alternativ kann die Python-Funktion string.format()
benutzt werden,
bei der die Platzhalter durch ein Paar von geschweiften Klammern festgelegt werden. Dabei gilt die Notation PlatzhalterNr:Formatierung.
import math # math Modul laden print('Der Wert von e ist %s und der von pi ist %s' % (math.e,math.pi)) print('Der Wert von e ist {} und der von pi ist {}'.format(math.e,math.pi)) print('Der Wert von e ist {:5.4f} und der von pi ist {:8.3f}'.format(math.e,math.pi)) print('Der Wert von e ist {1:5.4f} und der von pi ist {0:8.3f}'.format(math.e,math.pi))
Eine Liste aller Formattypen gibt es auf dieser Seite.
Formatierung von Zeichenketten mit f-Strings
Python hat ab Version 3.6 die sogenannten f-strings (formatted string literals) eingeführt, was zu einfacherem und lesbarerem Code führt.
print(f"2 + 3 is equal to {2+3}") variable = 'alignment!' print(f'foo {variable:>20} bar') print(f'foo {variable:<20} bar') print(f'foo {variable:^20} bar')
Die allgemeine Syntax ist: variable:{alignment}{width}
Eine etwas anspruchsvollere Ausgabe ergibt sich für die DataFrames des Pandas Moduls:
import pandas as pd df = pd.DataFrame.from_dict({'Value' :[234534.43, 987324543.34, 1234345.34, 8234.43]}) df['Currency'] = [f'${x:,.2f}' for x in df['Value']] df['Currency 2'] = df['Value'].apply(lambda x: f'${x:,.2f}') print(df)
print("\nPyramide 1:") maxN = 11 for i in range(maxN): x = "* " * i # Zeichenkette "* " i-mal wiederholen print(f'{x:^{maxN*2}}') # Zentriert auf 22 Zeichen ausgeben # ^^^
print("\nPyramide 2:") maxN = 11 for i in range(maxN): x = "* " * (maxN-i) # Zeichenketter (11-i)-mal wiederholen print(f'{x:^{maxN*2}}') # Wie 1 nur umgekehrte Reihenfolge # ^^^
print("\nPyramide 3:") maxN = 11 for i in range(maxN): x = '* ' * i # Wie 1 print(f'{x:<{maxN*2}}')# Wie 1, nur linksbündig # ^^^
print("\nPyramide 4:") maxN = 11 for i in range(maxN): x = '* ' * i # Wie 1 print(f'{x:>{maxN*2}}')# Wie 1, nur rechtsbündig # ^^^
Liste aller Stringfunktionen
Eine vollständige Liste an String-Funktionen erhält man, indem man die Funktion dir()
auf einen beliebigen String anwendet, wobei allerdings auch die internen Funktionen angegeben werden.
Eine vollständige Liste der Benutuzerfunktionen für Zeichenketten gibt es auf dieser Seite.
Listen und Tupel
Listen und Tupel sind faktisch Vektoren oder Matrizen, die eine Sequenz von Objekten beliebigen Datentyps als Liste speichern. Jedes Element einer Liste kann dabei von einem anderen Typ sein. Eine Liste wird in eckige Klammern gesetzt und ein Tupel in runde Klammern. Ein Tupel ist grundsätzlich wie eine Zeichenkette, nachdem sie definiert wurde, nicht mehr veränderlich. Sie bietet sich daher immer dann an, wenn man Anwender vor der unbeabsichtigten Modifikation einer Liste schützen will. Es handelt sich bei einer Liste und einem Tupel jeweils um kommaseparierte Folgen, die über die Funktionen gleichen Names in den jeweils anderen Typ gewandelt werden können.
liste0 = ['a', 'b', 'c', 1, 2, 3.14, True] tupel0 = ('a', 'b', 'c', 1, 2, 3.14, True) liste1 = list(('a', 'b', 'c', 1, 2, 3.14, True)) # Tupel in Liste wandeln print(liste0,liste1) if 3.14 in liste1: print("3.14 ist in der Liste") tupel1 = tuple(['a', 'b', 'c', 1, 2, 3.14, True]) # Liste in Tupel wandeln print(tupel0,tupel1) if True in tupel1: print("True ist in dem Tupel") print("liste0 hat ",len(liste0)," Elemente.") print("tupel0 hat ",len(tupel0)," Elemente.")
Indizierung von Listen und Tupeln
Der Zugriff auf die einzelnen Elemente erfolgt wie bei Zeichenketten, die letztlich nicht anderes als ein Tupel sind.
liste0 = ['a', 'b', 'c', 1, 2, 3.14, True] tupel0 = ('a', 'b', 'c', 1, 2, 3.14, True) print(liste0[0],tupel0[0]) # Erstes Element der Liste/Tupel print(liste0[5],tupel0[5]) # Sechstes Element der Liste/Tupel print(liste0[-2],tupel0[-2]) # Vorletztes Element der Liste/Tupel print(liste0[3:5],tupel0[3:5])# 4. und 5. Element print(liste0[3:],tupel0[3:]) # ab 4. Element print(liste0[:5],tupel0[:5]) # bis 5. Element print(liste0[1:5:2],tupel0[1:5:2]) # 2-er Schrittweite
# a[start:stop:step], default step is 1 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(a) b = a[1:3] # Note that the last index is not included print("1: ",b) b = a[2:] # until the end print("2: ",b) b = a[:3] # from beginning print("3: ",b) a[0:3] = [0] # replace sub-parts, you need an iterable here print("4: ",a) b = a[::2] # start to end with every second item print("5: ",b) a = a[::-1] # reverse the list with a negative step: print("6: ",a) b = a[:] # copy a list with slicing c = a # only a reference print("7: ",a,b,c) a.pop(0) print("8:, ",a,b,c)
Die Erweiterung von Tupeln ist möglich, jedoch in der Handhabung etwas gewöhnungsbedürftig, denn
Tupel können nur dann erweitert werden, wenn das anzuhängende Tupel bei der Definition ein abschließendes Komma aufweist,
wenn es nur aus einem Element besteht. Hat es mehr Elemente, so kann das Komma entfallen.
Dabei spielt es keine Rolle, ob zu erweiternde Tupel selbst mit einem Komma endet, wie beispielsweise das erste tupel1
im folgenden Beispiel:
tupel0 = ('a', 'b', 'c', 1, 2, 3.14, True) # kein Komma am Ende tupel1 = ('a', 'b', 'c', 1, 2, 3.14, True, ) # mit Komma am Ende print("0: ", tupel0) print("1: ", tupel1) t_Add = (False, "foo", ) # #t_Add = (False) # ergibt einen Fehler! (Ausprobieren) tupel0 = tupel0 + t_Add # ok tupel1 = tupel1 + t_Add # ok print("0: ", tupel0) print("1: ", tupel1) t_Add = (1,2,) tupel0 = tupel0 + t_Add tupel1 = tupel1 + t_Add print("0: ", tupel0) print("1: ", tupel1) t_Add = ("bar", "baz" ) # ok, obwohl hinten kein Komma! tupel0 = tupel0 + t_Add tupel1 = tupel1 + t_Add print("0: ", tupel0) print("1: ", tupel1)
Mehrdimensionale Listen
Eine Matrix besteht bekanntermaßen aus einzelnen Vektoren, was sich auch auf Listen übertragen lässt. Eine Liste, bei der jedes Element wiederum eine Liste ist (Verschachtelung), usw., wird als mehrdimensionale Liste bezeichnet. Auf diese können die gleichen Funktionen angewendet werden, wie für eine eindimensionale Liste. Für jede Dimension wird beim Zugriff ein paar an eckigen Klammern angegeben, sodass bei einer zweidimensionalen MAtrix bei zwei eckigen Klammern genau ein Element das Ergebnis ist. Es lassen sich auch hier BEreiche auswählen..
liste0 = [ ['a', 'b', 'c'], [ 'd', 'e', 'f'], [ 'g', 'h', 'i']] print("1: ",liste0) print("2: ",liste0[0]) print("3: ",liste0[1][2]) print("4: ",liste0[2][1]) print("5: ",liste0[:2][1:]) print("6: ",liste0[:1][2:])
Listen-Funktionen
Für Listen existieren Funktionen, die in der Form liste.funktionsname()
angewendet
werden können.
Listen verknüpfen
Durch liste_1.extend(liste_2)
kann liste_2 an liste_1 angehängt werden. Dabei ist zu beachten, dass liste_1
nach dem Aufruf um liste_2 erweitert ist, das Rückgabeergebnis der Funktion aber nur None ist. Listen können auch durch einfache
Addition oder Multiplikation verkettet werden. Zu beachten ist, dass die neue Liste nur um die Elemente erweitert wird. Im Gegensatz
dazu kann mit lste.append()
die komplette Liste als eigenständiges Element angehängt werden.
liste0 = [ ['a', 'b', 'c'], [ 'd', 'e', 'f'], [ 'g', 'h', 'i'] ] liste1 = [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] print(liste0.extend(liste1)) print(liste0) print(liste1) print() liste2 = liste0 + liste1 print(liste2) liste3 = 2 * liste1 print(liste3) print() liste0 = [1, 2, 3] liste1 = ['a', 'b', 'c' ] liste4 = liste0.append(liste1) print(liste4, liste0)
Listen sortieren
Mit der Funktionliste.sort()
können die Elemente einer Liste in aufsteigender und mit
list.reverse()
in absteigender Reihenfolge sortiert werden. Der Rückgabewert der Funktionen ist jeweils
None, d.h. es wird keine neue Liste erstellt, sondern die bestehende bearbeitet.
liste0 = [3, 1, -5, 8, 2] liste1 = liste0.sort() print(liste0, liste1) liste2 = liste0.reverse() print(liste0, liste2)
Neben der Funktion sort()
existiert eine weitere Variante, die jedoch die Liste selbst _nicht_ sortiert,
sondern nur die sortierte Liste zurückgibt. Vergleiche:
nums = [2, 3, 1, 5, 6, 4, 0] print("Anwendung von sort() wie oben:") print(nums.sort()) # None print(nums) # [0, 1, 2, 3, 4, 5, 6] print("\nAnwendung von sorted():") nums = [2, 3, 1, 5, 6, 4, 0] # print(sorted(nums)) # [0, 1, 2, 3, 4, 5, 6] sortierte Liste print(nums) # [2, 3, 1, 5, 6, 4, 0] alte unsortierte Liste
list.sort()
sollte immer dann verwendet werden, wenn eine dauerhafte Veränderung der Liste beabsichtigt
ist und die Wiederherstellung der ursprünglichen Reihenfolge der Elemente nicht erwünscht ist.
Anderenfalls sollte sorted()
verwendet werden, wenn das zu sortierende Objekt iterierbar ist
(z. B. Liste, Tupel, Wörterbuch, String) und das gewünschte Ergebnis eine sortierte Liste ist, die alle Elemente enthält.
Eine eingehende Beschreibung der verschiedenen Möglichkeiten findet man in sorting.html und speziell für dictionaries in sorting_dicts.html.
Elemente indizieren, einfügen und entfernen
Das Zählen und Suchen bestimmter Elemente in einer Liste erfolgt analog zu Zeichenketten:
liste0 = [ ['a', 'b', 'c'], [ 'd', 'e', 'f'], [ 'g', 'h', 'i']] liste1 = 2 * liste0 print("liste1: ",liste1) print("Es gibt ",liste1.count('a'), " 'a' in der Liste.") print("Es gibt ",liste1.count(['d','e','f']), " ['d','e','f'] in der Liste.") if ['e','f'] in liste1: print("['e','f']“ in liste1 gefunden") else: print("['e','f'] nicht in liste1 gefunden") if ['d','e','f'] in liste1: print("['d','e','f']“ in liste1 als ", liste1.index(['d','e','f'])+1,". Element gefunden!",sep="")# kein Zwischenraum else: print("['d','e','f']“ nicht in liste1 gefunden")
as Einfügen von Elementen in eine Liste (nicht Tupel!) erfolgt mit liste.insert(indexnummer, element)
und das Entfernen mit liste.remove(element)
, beziehungsweise liste.pop(indexnummer)
:
liste1 = [ ['a', 'b', 'c'], [ 'd', 'e', 'f'], [ 'g', 'h', 'i']] print("liste1: ",liste1) liste1.insert(0,"Johnny") liste1.insert(-1,"Mauser") print(liste1) liste1.remove("Mauser") print(liste1) liste2 = liste1.pop(0) # 1. Element entfernen print("liste1: ",liste1, "liste2: ",liste2) liste2 = liste1.pop() # Letztes Element entfernen print("liste1: ",liste1, "liste2: ",liste2)
Die Funktion liste.pop(indexnummer)
liefert das gelöscht Element zurück. Eine bestimmten Bereich einer Liste oder komplett löschen
lässt sich mit del liste[]
erreichen. Sollen nur die Elemente, aber nicht die Liste an sich gelöscht werden,
so lässt sich das mit liste.clear()
erreichen.
liste1 = [ ['a', 'b', 'c'], [ 'd', 'e', 'f'], [ 'g', 'h', 'i']] print("liste1: ",liste1) print(liste1.pop()) # letztes Element löschen print(liste1) liste2 = 4 * liste1 print(liste2) del liste2[3:6]# Löschen der Elemente 3, 4, 5 print(liste2) liste2.clear() # Listenelemente löschen, Liste bleibt definiert print(liste2)
Listen kopieren
Die Anweisungliste1 = liste0
ist keine echte Kopie der Liste, sondern nur
eine Kopie des Namens. Die neue Liste zeigt auf dieselben Elemente wie die alte Liste.
Von dieser ein Element gelöscht, so fehlt es auch in der "Kopie". Eebenso ergibt eine Veränderung von liste1
die gleiche Veränderung in liste0. Bei einer echten Kopie mit liste.copy()
passiert das nicht;
es existieren dann zwei unabhängige Listen.:
liste0 = [ ['a', 'b', 'c'], [ 'd', 'e', 'f'], [ 'g', 'h', 'i']] liste1 = liste0 print("liste0: ",liste0) print("liste1: ",liste1) print(liste0.pop()) # letztes Element von liste0 löschen und anzeigen liste1[1] = [ "Johnny Mauser" ] # 2. Element in liste1 neu definieren print("liste0: ",liste0) # ebenfalls mit "Johnny Mauser" print("liste1: ",liste1) # ebenfalls ohne letztes Element liste2 = liste0.copy() # erzeuigen einer echten Kopie liste2.append([ "Franz von Hahn" ]) # an liste2 anhängen print("liste0: ",liste0) # ohne "Franz von Hahn" print("liste2: ",liste2) # mit "Franz von Hahn"
Visuelle Zusammenfassung der Listenoperationen
Alle Funktionen gibt es auch hier https://docs.python.org/3/tutorial/datastructures.html erklärt!
List-Comprehensions
Dies ist eine vereinfachte Methode, um eine Liste mit Elementen automatisiert zu füllen:
from math import * # alles importieren l1 = [i for i in range(5)] print(l1) l2 = [sqr(i) for i in range(5)] print(l2)
Die Fibonacci-Zahlenreihe ergibt sich durch Addition der zwei vorhergehenden Elemente: 1 1 2 3 5 8 ...
f1 = 0 f2 = 1 fib = [] for i in range(0, 10): fib. append(f1) temp = f1+f2 f1 = f2 f2 = temp print(fib)
Durch Komprimierung der Schleife lässt sich das vereinfachen.
fib = [0,1] [fib.append(fib[-2]+fib[-1]) for i in range(8)] print(fib)
Gegeben sei eine Liste der ersten 100 natürlichen Zahlen ohne Null durch nat100 = range(1,101)
Es soll eine neue Liste der Primzahlen bis 100 erstellt werden. Dazu kann man über
die einzelnen Elemente der Liste iterieren, der sogenannten List-Comprehension.
Durch definierte Filter kann die neue Liste an Bedingungen geknüpft werden.
Im folgenden Beispiel kommt die natürliche Zahl n
nur dann in die Liste, wenn es eine
Primzahl ist.
import math # für math.sqrt (Wurzel) def is_prime(n): # Überprüfe n return not any(n % p == 0 for p in range(2, int(math.sqrt(n)) + 1)) # p Laufvariable # any() gibt true zurück wenn mindestens einmal eine Division ohne Rest möglich ist # not any() ist dann true, wenn keine Division ohne Rest möglich ist -> Primzahl nliste = range(1,101) prim_liste = [ i for i in nliste if is_prime(i) ] # i nur dann in die Liste, wenn Primzahl print(prim_liste) print("Insgesamt ", len(prim_liste), " Primzahlen.", sep="")
Für any
und all
siehe auch all_any.html
Es ist auch möglich, Elemente aus zwei Listen an Bedingungen zu knüpfen und dann in eine Liste zu setzen.
import random liste0 = [random.randint(1,51) for i in range(50)] # Zufallszahlen 1..50 liste1 = [random.randint(1,51) for i in range(50)] # " print(liste0) # zufällig verteilte Liste print(liste1) # " " " print() liste2 = [ i for i in liste0 if i in liste1 ] # i nur dann in die Liste, wenn in liste0 und 1 liste0.sort() # sortierte Liste liste1.sort() # " " print(liste0) print(liste1) print() liste2.sort() print(liste2) print("Insgesamt ", len(liste2), " gemeinsame Zahlen.", sep="") print() liste3 = [] for i in range(len(liste2)): if liste2[i] not in liste3: # nur in liste3 hinzufügen, wenn nicht schon vorhanden liste3.append(liste2[i]) print(liste3) print("Insgesamt ", len(liste3), " echte gemeinsame Zahlen.", sep="")
Ebenso können bei gleich langen Listen alle Elemente beispielsweise dividieren. Der Zugriff erfolgt dann über die Laufvariable.
liste_1 = [1, 2, 3, 4, 8] liste_2 = [2, 30, 4, 15, 6] liste_div = [liste_1[i] / liste_2[i] for i in range(len(liste_1))] print(liste_div)
Listen-Destrukturierung ("packing und unpacking")
In Zuweisungen kann der Inhalt eienr iterierbaren Liste einzelnen VAriablen zugeordent werden, was auch als "unpacking" bezeichnet wird:
a, b = ( 1, 2 ) print (a,b)
Hierbei muss der Anwender selbst sicherstellen, dass die Liste mindestens so viele
Variablen enthält wie zugewiesen werden sollen. Anderenfalls gibt es eine Fehlermeldung.
Eine Liste unbekannter Länge kann über eine spezielle Syntax "entpackt" werden,
wobei head
ein Skalar und tail
eine Liste ist:
head, *tail = [ 1, 2, 3, "a", 5 ] print (head, tail) L_0 = [1, 2, 3, "a",5 ] head = L_0[0] # Alternative tail = L_0[1: ] print(head, tail)
Diese Syntax kann auch auf mehrere Zuweisungen ausgedehnt werden, die jeweils alle Werte bis zum Ende der Liste beachten. Im folgenden Bespsiel bekommt b den zweiten und z den letzten Wert zugewiesen, sodass other alle verbleibenden Werte als Liste zugeordnet werden:
a, b, *other, z = [1, 2, 3, "a", 5 ] print (a, b, other, z, sep="; ")
Ist man nur an bestimmten Werten der Liste interessiert, so können einzelne Elemente mit dem Operator _
ignoriert werden, wobei zu beachten
ist, dass dieser OPerator letztlich wie eine Variable funktioniert.
a, _ = [ 1 , 2 ] print (a) a, _, c = ( 1 , 2 , 3 ) print (a, c) a, b, *_ = [ 1, 2, 3, "a", 5 ] # Nur Python Version > 3.0 print (a, b) a, *_, b = [ 1, 2, 3, "a", 5 ] print (a, b) a, _, b, _, c, *_ = [ 1, 2, 3, "a", 5, "b" ] print (a, b, c)
Gleiches Verhalten kann man auch mit Funktionen und deren Parameter erreichen. Normalerweise muss eine Funktion alle Parameter definieren, die im Funktionskörper benutzt werden:
def func_1(arg1 , arg2 , arg3): return (arg1 , arg2 , arg3) func_1( 1, 2, 3 )
Alternativ war auch die Anwendung des key-value-Systems möglich, was unterschiedliche Aufrufe zulässt:
Übergibt man mit dem *-Operator eine Liste, so wird diese automatisch entpackt und als einzelne Parameter verwendet:
L_0 = [ 1, 2, 3 ] def func_3(arg1, arg2, arg3): return (arg1 , arg2 , arg3) print(func_3( *L_0)) print(func_3(*['w', 't', 'f']))
Auch hier muss die Zahl der Elemente der Liste der Zahl der erwarteten Parameter der aufgerufenen Funktion entsprechen. Anderenfalls gibt es eine Fehlermeldung.
Der Doppelsternoperator kann genutzt werden, wenn statt der Liste ein Dictionary mit den entsprechenden Parameterbezeichnungen übergeben wird.
d_0 = { 'arg1' : 1, 'arg2' : 2, 'arg3' : 3 } def func_3(arg1, arg2, arg3): return (arg1, arg2, arg3) def func_4(arg1="a", arg2="b", arg3="c"): return (arg1, arg2, arg3) print(func_3( **d_0)) print(func_3(*['w', 't', 'f'])) print() print(func_4( *[1])) print(func_4( **{'arg2': 2})) print() def func_5(arg1, arg2="b", arg3="c"): return (arg1, arg2, arg3) print(func_5( *[1])) print(func_5( *[1, 2, 3])) print(func_5( **{'arg1': 1})) print(func_5( *[1, 2], **{'arg3': 3}))
Die Definition einer Funktion ohne genaue Kenntnis über die Zahl und Position der übergebenen Parameter ist ebenfalls mit den Stern-Operatoren möglich:
def func_1(*args , **kwargs): # *args and **kwargs are special parameters that are set to a tuple and a dict print(args, kwargs) # ignoriert den Rückgabewert "None" (wird _ zugeordnet) _ = func_1(1, 2, 3) # tuple, empty dict _ = func_1(a=1, b=2, c=3) # empty tuple and dict _ = func_1('x', 'y', 'z', a=1, b=2, c=3) # tuple and dict
Die Sternvarianten werden sehr häufig benutzt, um nicht festgelegte PArametersequnzen an FUnktionen zu übertragen. Im Folgenden ein BEispiel bei dem die String-Klasse erweitert wird:
class A: # Basisklasse def __init__(self, *args, a, **kwargs): # beliebige Argumente, kw a, beliebige keywords print("A", *args, a, dict(**kwargs), sep="; ") class B(A): def __init__(self, arg1, *args, b, **kwargs): # arg1, beliebige Argumente, kw b, beliebige keywords print("B vorher", arg1, b, *args, dict(**kwargs), sep="; ") super(B, self).__init__(*args, **kwargs) # A aufrufen und "erben" print("B nachher", arg1, b, *args, dict(**kwargs), sep="; ") class A1(A): def __init__(self, arg1, *args, a1, **kwargs): # arg1, beliebige Argumente, kw a1, beliebige keywords print("A1 vorher", arg1, a1, *args, dict(**kwargs), sep="; ") super(A1, self).__init__(*args, **kwargs) # A aufrufen und "erben" print("A1 nachher", arg1, a1, *args, dict(**kwargs), sep="; ") class B1(A1, B): def __init__(self, arg1, *args, b1, **kwargs): # arg1, beliebige Argumente, kw b1, beliebige keywords print("B1 vorher", arg1, b1, *args, dict(**kwargs), sep="; ") super(B1, self).__init__(*args, **kwargs) # Erst A1, dann B aufrufen und "erben" print("B1 nachher", arg1, b1, *args, dict(**kwargs), sep="; ") B1(1, 2, 3, a1=6, b1=5, b="hello", a=None)
Tipps und Tricks
Named Tuple
Rückgabe eines Tuples mit Zugriff durch Namen auf die einzelnen Elemente:
from collections import namedtuple def multiple_values(): MyTuple = namedtuple("MyTuple", ["name", "age", "car"]) # Name, [Elemente] name = "Mark" age = 21 car = "Ford" return MyTuple (name, age, car) # Calling the function result = multiple_values() name = result.name age = result.age car = result.car print(f"Name: {name}, Age: {age}, Car: {car}")
Elemente von beiden Seite einer Liste löschen (pop)
Wenn man Elemente an beiden Seiten einer Liste hinzufügen oder entfernen
möchte, so kann man deque
(double-ended queue) verwenden.
Anders als bei einer normalen Liste, bei der man Elemente nur am Ende hinzufügen oder entfernen kann,
kann dies mit deque
an beiden Seiten erfolgen
from collections import deque my_list = deque([1, 3]) # appending on the left end of the list my_list.appendleft(5) # appending on the right end of the list mylist.append (7)# right is the default print(my_list) print() my_list = deque([1, 3, 9, 6]) # pop element on the left end of the list my_list.popleft # pops 1 # pop element on the right end of the list my_list.pop() # pops 6 print(my_list)
Mengen mit set() und frozenset
Ein Set (eine Menge) bezeichnet in Python eine Sammlung an Objekten beliebigen Datentyps, wobei jedes
Objekt nur ein einziges Mal in der Menge enthalten sein darf. Sets werden in Python in
geschweifte Klammern gesetzt: Durch Anwendung von Operatoren auf paarweise je zwei
Sets können nach den allgemein bekannten Regeln der Mengenlehre neue Sets gebildet werden.
Da Sets ein Element nur jeweils einmal enthalten können, können mit set()
aus einer
Liste doppelte Einträge entfernt werden.
set_1 = { 'a', 'b', 'c', 1, 2, 3 } set_2 = set( [ 'a', 'b', 'c', 1, 2, 2, 3, 3 ] ) # doppelte Einträge werden entsorgt liste_2 = list(set_2) set_3 = { 'b', 'c', 'd', 2, 3, 4 } print(set_1) print(set_2, liste_2) print(set_3) # Schnittmenge: set_4 = set_1 & set_2 print(set_4) # Vereinigungsmenge: set_5 = set_1 | set_2 print(set_5) # Differenzmenge: set_6 = set_1 \ set_2 print(set_6) # Symmetrische Differenz (Entweder-Oder): set_7 = set_1 ^ set_2 print(set_7) # Test, ob set_1 eine Obermenge von set_2 ist: istObermenge = set_1 > set_2 print(istObermenge)
Es existieren die folgenden speziellen Funktionen für Sets:
set.add()
zum Hinzufügen von Elementen zu einer Menge hinzufügen.set.discard()
zum Entfernen von Elementen aus einer Menge.set.copy()
zum Erstellen einer Kopie einer Menge.set.clear
zum Löschen aller Elemente einer Menge, wobei sie selbst definiert bleibt.frozenset()
dict – Wörterbücher
Hiermit werden key-value-Paare unterstützt; ein bestimmter key verweist auf einen value (Eintrag).
Dabei entsteht ein sogenanntes Dictionary, in Kurzform dict
Zur Darstellung von dict werden in Python geschweifte Klammern verwendet. Schlüssel und zugehörige Werte werden durch
einen Doppelpunkt voneinander getrennt. Die einzelnen Schlüssel-Wert-Paare entsprechen einer Liste und werden daher durch Komma voneinander
getrennt.
gehaltsliste = { "Müller" : 3414.15, "Meyer" : 1414.12, "Schnasebeutel" : 2452.03, "Krachulke" : 3312.89, } print("Das Gehalt von Krachulke beträgt ",gehaltsliste["Krachulke"], "€",sep="") print("und das von Müller beträgt ",gehaltsliste["Müller"], "€",sep="") print() gehaltsliste["Schulze"] = 2342.12 # Zur Gehaltsliste hinzufügen gehaltsliste.update( {"Schnasebeutel" : 2452.13 } ) summeGehalt = 0 for i in gehaltsliste.values(): summeGehalt += i print("Die gesammte Summe an Gehältern beträgt ",summeGehalt, "€",sep="") print() sortedListe = dict(sorted(gehaltsliste.items()))# nur für Python Version > 3.6 txt = "{:14} {:.2f}" for key, value in sortedListe.items(): print(txt.format(key, value))
sorted(gehaltsliste.items())
liefert selbst kein Dictionary zurück,
sondern eine Liste von Tupelpaaren. Mit dict()
kann diese aber
problemlos in ein Dictionary gewandelt werden:
gehaltsliste = { "Müller" : 3414.15, "Meyer" : 1414.12, "Schnasebeutel" : 2452.03, "Krachulke" : 3312.89, } sortedListe = sorted(gehaltsliste.items()) print(type(sortedListe)) print(sortedListe) print() dictSortedListe = dict(sorted(gehaltsliste.items()))# Um wandlung in ein dict print(type(dictSortedListe)) print(dictSortedListe)
Das Sortieren nach den zugewiesenen Werten (values) ist etwas umständlicher, da die Schlüssel, die auf diese verweisen, gesondert gehandhabt werden müssen:
gehaltsliste = { "Müller" : 3414.15, "Meyer" : 1414.12, "Schnasebeutel" : 2452.03, "Krachulke" : 3312.89, } print("Das Gehalt von Krachulke beträgt ",gehaltsliste["Krachulke"], "€",sep="") print("und das von Müller beträgt ",gehaltsliste["Müller"], "€",sep="") print() gehaltsliste["Schulze"] = 2342.12 # Zur Gehaltsliste hinzufügen gehaltsliste.update( {"Schnasebeutel" : 2452.13 } ) summeGehalt = 0 for i in gehaltsliste.values(): summeGehalt += i print("Die gesammte Summe an Gehältern beträgt ",summeGehalt, "€",sep="") print() sortedListe = dict(sorted(gehaltsliste.items()))# nur für Python Version > 3.6 txt = "{:14} {:.2f}" print("Sortiert nach Namen:") for key, value in sortedListe.items(): print(txt.format(key, value)) print() print("Sortiert nach Gehalt:") sorted_values = sorted(gehaltsliste, key=gehaltsliste.get, reverse=True) for r in sorted_values: print(txt.format(r, gehaltsliste[r]))
sorted(gehaltsliste, key=gehaltsliste.get, reverse=True)
liefert selbst kein Dictionary zurück,
sondern nur eine Liste der nach Values sortierten Keys zutück. Mit dict()
kann diese aber
nicht in ein Dictionary gewandelt werden, denn die Zuordnung key->value ist verloren gegangen.
Die Werte der jeweiligen Keys sind aber nach wie vor in der Ausgangsliste gespeichert,
sodass das Dictionary neu aufgebaut werden kann:
gehaltsliste = { "Müller" : 3414.15, "Meyer" : 1414.12, "Schnasebeutel" : 2452.03, "Krachulke" : 3312.89, } sorted_values = sorted(gehaltsliste, key=gehaltsliste.get, reverse=True) print(type(sorted_values)) print(sorted_values) print() d_neu = {} for key in sorted_values: d_neu[key] = gehaltsliste[key] print(d_neu)
Eine eingehende Beschreibung der verschiedenen Möglichkeiten zum Sortieren von dictionaries findet man in sorting_dicts.html. Eine Einführung zum Sortieren generell findet man in sorting.html.
Dictionaries können ebenfalls zum "Übersetzen" (translate) von Textdateien genutzt werden: BEISPIELE
Anstelle von Zeichenketten können auch Zahlen oder alle unveränderbaren Objekte genutzt werden.
Veränderbare Objekttypen, wie Listen, sind als Schlüssel nicht erlaubt.
Mit dictkeys()
, dict.values()
und dict.items()
lassen sich so genannte
„Views“ eines Wörterbuchs erzeugen. Bei einem View handelt es sich um eine Listenvariable,
die automatisch aktualisiert wird, wenn das zugehörige dict geändert wird.
Zusammenstellung der Dictionary Methoden
Methode | Beschreibung |
---|---|
clear() | Removes all the elements from the dictionary |
copy() | Returns a copy of the dictionary |
fromkeys() | Returns a dictionary with the specified keys and value |
get() | Returns the value of the specified key |
items() | Returns a list containing a tuple for each key value pair |
keys() | Returns a list containing the dictionary's keys |
pop() | Removes the element with the specified key |
popitem() | Removes the last inserted key-value pair |
setdefault() | Returns the value of the specified key. If the key does not exist: insert the key, with the specified value |
update() | Updates the dictionary with the specified key-value pairs |
values() | Returns a list of all the values in the dictionary |
Anwendungen
Das folgende Beispiel benötigt die komma-separierte Liste Datenbank coop_coffee.csv. Speichern Sie diese auf Ihrem Rechner.
# Beispiel coop_coffee.py # benötigt die angegebenen Pakete # from matplotlib import pyplot import numpy import re data = numpy.recfromcsv('coop_coffee.csv', delimiter='\t',encoding="utf8")# array of tuple #print(data) #print(type(data)) cat_names = ('misc', 'pieces', 'instant', 'grains', 'grinded')# tuple # Versch., Pads, Instant, Bohnen, gemahlen #print(type(cat_names)) #print(cat_names) categories = dict((name, []) for name in cat_names)# dict name:[] #print(type(categories)) #print(categories) categories['pieces'] = [row for row in data if re.search("pièces|portions|sachet|capsule|nescafé dolce gusto", row[2], re.IGNORECASE)] #print("pièces|portions|sachet|capsule|nescafé dolce gusto") #print(categories['pieces']) categories['instant'] = [row for row in data if re.search("soluble|instant", row[2], re.IGNORECASE)]# Fertigkaffee categories['grains'] = [row for row in data if re.search("grains", row[2], re.IGNORECASE)]# Bohnen categories['grinded'] = [row for row in data if re.search("moulu", row[2], re.IGNORECASE)]# Gemahlt #print(sum(categories.values(), [])) sum_categories_set = set([ tuple(t) for t in sum(categories.values(), []) ]) #print(sum_categories_set) #print("sum_categories_set: ",type(sum_categories_set)) categories['misc'] = set(list(data.tolist())) - sum_categories_set pyplot.gca().set_prop_cycle(color=['lightGray', 'red', 'blue', 'green', 'yellow'])# gca get-current-axis for name in cat_names: rows = categories[name] x = [r[0] for r in rows] y = [r[1] for r in rows] xy_label = "%s (%d)" % (name, len(rows)) pyplot.plot(x, y, marker='o', alpha=0.75, linestyle='none', label=xy_label) pyplot.title("Coffee, Coop, July 2012") pyplot.xlabel("Price [CHF]") pyplot.ylabel("Weight [Kg]") pyplot.ylim(0, 1.05) pyplot.xlim(0, 21) pyplot.grid() pyplot.legend(numpoints=1, loc="right") pyplot.savefig('coop_coffee.png') pyplot.show()
Lösungen der Übungen
k = 1 # Startwert maxN = 1000 for i in range(1, maxN): # Bereich 1,2,3,...maxN-1 k = k * i # n-1*n #print(k) # Die Zahl n! print(len(str(k))) # Anzahl Ziffern ## jetzt mit 10000 ## maxN = 10000 for i in range(1, maxN): # Bereich 1,2,3,...maxN-1 k = k * i # n-1*n #print(k) # Die Zahl n! print(len(str(k))) # Anzahl Ziffern
k = 1 # Startwert k0 = 0 i = 0 while True: i += 1 k = k * i # n-1*n l = len(str(k)) if (l == 12345): print(str(i)+"! hat genau 12345 Stellen") break elif(l > 12345): print("\nEin n! mit genau 12345 Stellen existiert nicht!") print(str(i-1)+"! hat "+str(len(str(k0)))+" Stellen und "+str(i)+"! hat "+str(l)+" Stellen.") break k0 = k # n-1 #print(k)
Nächste Kurseinheit: 02 Fallunterscheidungen