[Python] List Slicing
Was ist List Slicing?
Mit List Slicing ist es möglich, Teillisten aus einer Liste zu extrahieren.
Die Syntax
1 | new_list = my_list[start_index:end_index] |
Folgend ein paar Beispiele und die Erklärungen dazu:
1 2 3 4 | my_list = [1, 2, 3, 4, 5] print(my_list) new_list = my_list[0:3] print(new_list) |
Output:
[1, 2, 3, 4, 5] [1, 2, 3]
my_list = [1, 2, 3, 4, 5]Hier wird eine Liste mit fünf Elementen erstellt
new_list = my_list[0:3]Aus dieser Liste wird jetzt eine Teilliste von Element 1 bis 3 (Index 0 bis 2) extrahiert und in "new_list" gespeichert.
Ihr müsst darauf achten, dass im obigen Beispiel Elemente mit dem Index 0, 1 und 2 extrahiert werden.
Das heißt, dass entgegen der Vermutung "[0:3]" das Element an Index 3 nicht mit extrahiert wird.
Das ist eine Eigenart des Slicings, dass der vom Doppelpunkt (":") linksstehende Index einschließlich und der vom Doppelpunkt rechtsstehende Index ausschließlich zu betrachten ist.
Mit diesem Wissen schauen wir uns noch ein paar Beispiele an:
1 2 3 4 | my_list = [1, 2, 3, 4, 5] print(my_list) new_list = my_list[2:4] print(new_list) |
Output:
[1, 2, 3, 4, 5] [3, 4]
Wieder gut zu sehen, es wurde von Index 2 bis einschließlich Index 3 eine Teilliste extrahiert. Also zwei Elemente.
Negative Indizes
Eine Besonderheit, aber nicht auf das Slicing beschränkt, ist, dass bei Übergabe eines negativen Indexes keine Fehlermeldung ausgegeben wird, sondern die Elemente von hinten an gezählt werden.
Wie das aussieht, zeigen folgende Beispiele:
1 2 | my_list = [1, 2, 3, 4, 5] print(my_list[-1]) |
Output:
5
Wie ihr hier sehen könnt, wird bei Übergabe des negativen Indexes "[-1]" das letzte Element der Liste zurückgegeben.
Also wird von hinten und von 1 bzw. -1 an gezählt?
Genau! Und das macht auch Sinn, denn von vorne wird von 0 an gezählt und da von hinten natürlich nicht von -0 gezählt werden kann, wird von -1 an gezählt.
Folgend noch ein Beispiel und dann geht's weiter mit Slicing:
1 2 | my_list = [1, 2, 3, 4, 5] print(my_list[-3]) |
Output:
3
Slicing mit negativen Indizes
Das Slicing geht auch mit negativen Indizes:
Output:
Hier wird eine Liste von 2 bis 4 extrahiert, denn von hinten bei -1 angefangen zu zählen bis -4, landen wir auf der Zahl 2 (-1 = 5, -2 = 4, -3 = 3, -4 = 2) und von vorne bei der 0 angefangen bis 3 zu zählen (Index 4 ausgeschlossen) landen wir auf der 4.
Verwirrt? Es geht noch weiter...
1 2 3 4 | my_list = [1, 2, 3, 4, 5] print(my_list) new_list = my_list[-4:4] print(new_list) |
Output:
[1, 2, 3, 4, 5] [2, 3, 4]
Hier wird eine Liste von 2 bis 4 extrahiert, denn von hinten bei -1 angefangen zu zählen bis -4, landen wir auf der Zahl 2 (-1 = 5, -2 = 4, -3 = 3, -4 = 2) und von vorne bei der 0 angefangen bis 3 zu zählen (Index 4 ausgeschlossen) landen wir auf der 4.
Verwirrt? Es geht noch weiter...
Slicing und Schrittgröße
Über einen zweiten Doppelpunkt und somit einen dritten Parameter, dem "step"-Parameter, ist es möglich, die Schrittgrösse beim zählen zu bestimmen.
Wie sieht das Ganze aus?
Schauen wir uns das folgende Beispiel an:
Output:
Ok, zerlegen wir das Ganze mal:
Jetzt stellt ihr euch vielleicht die Frage: was passiert, wenn die Anzahl der durchzuzählenden Elemente nicht mit der Schrittgrösse teilbar ist?
Schauen wir uns dazu einfach das nächste Beispiel an, was dem obigen sehr ähnlich ist:
Interessant ist hier aber diese Zeile:
In diesem Statement würde man doch einen Widerspruch erwarten, denn mit einer Schrittweite von 3 kann man nicht von 0 bis 4 Zählen.
Gehen wir das mal durch:
Schritt 1 = Index 0
Schritt 2 = Index 3
Schritt 3 = Index 6 ?
Index 6 gibt es in dieser Liste nicht, und außerdem wollen wir nur bis Index 4 zählen... seltsam!
Schauen wir uns einfach mal den Output an:
Aha, es wird einfach nicht mehr weiter gezählt!
Fassen wir also zusammen: die gute Nachricht ist, dass das Programm nicht durch einen Fehler beendet wird, was wiederum auch die schlechte Nachricht ist, denn das kann zu einem seltsamen Verhalten eures Programms führen und ihr findet die Ursache nicht.
Warum erwähne ich das hier so genau?
Ich möchte, dass ihr über diesen Umstand bescheid wisst, dass Python bei solchen Fällen keine Fehlermeldung bringt und quasi selber bemerkt, dass mit dieser Schrittgrösse nicht Zielgenau zum bestimmten Element gezählt werden kann. Es wird einfach vorher aufgehört zu zählen!
So, und nun wisst ihr darüber bescheid! - Weiter geht's... :)
Output:
Und weil es so schön ist, dass das auch bei Strings funktioniert, gleich noch ein Beispiel:
Output:
Macht genau das selbe
Von hier bis zum Ende
Möchtet ihr die Liste von einer bestimmten Stelle bis zum Ende Slicen, dann müsst ihr das Ende nicht extra bestimmen und angeben:
Lasst einfach die Angabe für das Ende weg...
Ich will alles
Möchtet ihr die komplette Liste slicen (also kopieren), so könnt ihr das ohne Angabe von Anfang und Ende:
Keine Angaben, aber mit Schrittgrösse bitteschön!
Möchtet ihr beim obigen Beispiel trotzdem einen "step"-Parameter mit Angeben, so könnt ihr das wie folgt:
1 2 3 4 | my_list = [1, 2, 3, 4, 5] print(my_list) new_list = my_list[0:6:2] print(new_list) |
Output:
[1, 2, 3, 4, 5] [1, 3, 5]
Ok, zerlegen wir das Ganze mal:
new_list = my_list[0Hier sagen wir, dass wir von vorne anfangen wollen zu zählen (Start bei Zahl 1)
new_list = my_list[0:6Hier, dass wir bis zum Index 6 -1, also Index 5 zählen möchten (Ende bei Zahl 5)
new_list = my_list[0:6:2]Und hier, dass nur jedes zweite Element gezählt werden soll (1, 3, 5)
Jetzt stellt ihr euch vielleicht die Frage: was passiert, wenn die Anzahl der durchzuzählenden Elemente nicht mit der Schrittgrösse teilbar ist?
Schauen wir uns dazu einfach das nächste Beispiel an, was dem obigen sehr ähnlich ist:
1 2 3 4 | my_list = [1, 2, 3, 4, 5] print(my_list) new_list = my_list[0:6:3] print(new_list) |
Interessant ist hier aber diese Zeile:
new_list = my_list[0:6:3]Eine Schrittgrösse von 3, gezählt von Element 1 bis 5 (Index 0 bis 4)
In diesem Statement würde man doch einen Widerspruch erwarten, denn mit einer Schrittweite von 3 kann man nicht von 0 bis 4 Zählen.
Gehen wir das mal durch:
Schritt 1 = Index 0
Schritt 2 = Index 3
Schritt 3 = Index 6 ?
Index 6 gibt es in dieser Liste nicht, und außerdem wollen wir nur bis Index 4 zählen... seltsam!
Schauen wir uns einfach mal den Output an:
[1, 2, 3, 4, 5] [1, 4]
Aha, es wird einfach nicht mehr weiter gezählt!
Fassen wir also zusammen: die gute Nachricht ist, dass das Programm nicht durch einen Fehler beendet wird, was wiederum auch die schlechte Nachricht ist, denn das kann zu einem seltsamen Verhalten eures Programms führen und ihr findet die Ursache nicht.
Warum erwähne ich das hier so genau?
Ich möchte, dass ihr über diesen Umstand bescheid wisst, dass Python bei solchen Fällen keine Fehlermeldung bringt und quasi selber bemerkt, dass mit dieser Schrittgrösse nicht Zielgenau zum bestimmten Element gezählt werden kann. Es wird einfach vorher aufgehört zu zählen!
So, und nun wisst ihr darüber bescheid! - Weiter geht's... :)
Slicen von Strings
Da Strings, also Zeichenketten intern auch nur Listen sind welche Charaktere enthalten (Buchstaben, Zahlen, Sonderzeichen etc.), kann man das Slicing genauso auch auf diese anweden:
1 2 3 4 | my_string = "Hallo Welt" print(my_string) new_string = my_string[0:5] print(new_string) |
Output:
Hallo Welt Hallo
Und weil es so schön ist, dass das auch bei Strings funktioniert, gleich noch ein Beispiel:
1 2 3 4 | my_string ="Hallo Welt" print(my_string) new_string = my_string[-4:] print(new_string) |
Output:
Hallo Welt Welt
Tipps und Tricks
Abschließend noch ein paar Tipps und Tricks, wie ihr mit Listen und Slicing noch besser umgehen könnt.
Die Null ist überflüssig
Bei folgendem Ausdruck...
new_list = my_list[0:6]
könnt ihr die Angabe der "0" auch weglassen:
new_list = my_list[:6]
Von hier bis zum Ende
Möchtet ihr die Liste von einer bestimmten Stelle bis zum Ende Slicen, dann müsst ihr das Ende nicht extra bestimmen und angeben:
new_list = my_list[2:6]
Lasst einfach die Angabe für das Ende weg...
new_list = my_list[2:]... und Python zählt automatisch bis zum Schluss der Liste
Ich will alles
Möchtet ihr die komplette Liste slicen (also kopieren), so könnt ihr das ohne Angabe von Anfang und Ende:
new_list = my_list[:]
Keine Angaben, aber mit Schrittgrösse bitteschön!
Möchtet ihr beim obigen Beispiel trotzdem einen "step"-Parameter mit Angeben, so könnt ihr das wie folgt:
zB. die Schrittgöße 2new_list = my_list[::2]
Comments
Post a Comment