[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]
Extrahiert aus "my_list" eine neue Teilliste welche aus den Elementen von einschließlich dem Index "start_index" bis ausschließlich dem Index "end_index" besteht.


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
Hier wird das dritte Element von hinten, angefangen von -1 zu zählen, zurückgegeben.



Slicing mit negativen Indizes


Das Slicing geht auch mit negativen Indizes:

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:

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[0
Hier sagen wir, dass wir von vorne anfangen wollen zu zählen (Start bei Zahl 1)

new_list  = my_list[0:6
Hier, 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]
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:

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:

new_list = my_list[::2]
zB. die Schrittgöße 2







Comments

Popular posts from this blog

[Python] Passwort cracker for Zip-archives

[Python] Writing csv files and reading them (simplified)

WebGL 2 Guide - #7 Das erste Dreieck