Ich brauche eine gute Erklärung (Referenzen sind ein Plus) auf Python & #39; s slice Notation.
Für mich, diese Notation braucht ein bisschen abholen.
Es sieht extrem mächtig aus, aber ich habe nicht ganz meinen Kopf um es bekommen.
Es ist eigentlich ganz einfach:
a[start:stop] # items start through stop-1
a[start:] # items start through the rest of the array
a[:stop] # items from the beginning through stop-1
a[:] # a copy of the whole array
Es gibt auch den Wert step
, der mit jedem der oben genannten Werte verwendet werden kann:
a[start:stop:step] # start through not past stop, by step
Der wichtigste Punkt ist, dass der "stop"-Wert den ersten Wert darstellt, der sich nicht im ausgewählten Slice befindet. Der Unterschied zwischen "stop" und "start" ist also die Anzahl der ausgewählten Elemente (wenn "step" 1 ist, die Vorgabe).
Die andere Eigenschaft ist, dass start
oder stop
eine negative Zahl sein kann, was bedeutet, dass vom Ende des Arrays statt vom Anfang gezählt wird. Also:
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items
In ähnlicher Weise kann auch step
eine negative Zahl sein:
a[::-1] # all items in the array, reversed
a[1::-1] # the first two items, reversed
a[:-3:-1] # the last two items, reversed
a[-3::-1] # everything except the last two items, reversed
Python ist freundlich zum Programmierer, wenn es weniger Elemente gibt, als man verlangt. Wenn Sie zum Beispiel nach a[:-2]
fragen und a
nur ein Element enthält, erhalten Sie eine leere Liste anstelle eines Fehlers. Manchmal würde man den Fehler vorziehen, also muss man sich bewusst sein, dass dies passieren kann.
slice()
ObjektDer Slicing-Operator []
wird im obigen Code mit einem slice()
Objekt unter Verwendung der :
Notation (die nur innerhalb von []
gültig ist) verwendet, d.h.:
a[start:stop:step]
ist äquivalent zu:
a[slice(start, stop, step)]
Slice-Objekte verhalten sich auch leicht unterschiedlich in Abhängigkeit von der Anzahl der Argumente, ähnlich wie bei range()
, d.h. sowohl slice(stop)
als auch slice(start, stop[, step])
werden unterstützt.
Um die Angabe eines bestimmten Arguments zu überspringen, kann man None
verwenden, so dass z.B. a[start:]
äquivalent ist zu a[slice(start, None)]
oder a[::-1]
äquivalent ist zu a[slice(None, None, -1)]
.
Während die :
-basierte Notation sehr hilfreich für einfaches Slicing ist, vereinfacht die explizite Verwendung von slice()
-Objekten die programmatische Erzeugung von Slicing.
Das Python-Tutorial spricht darüber (scrollen Sie ein wenig nach unten, bis Sie zu dem Teil über das Slicing kommen).
Das ASCII-Diagramm ist ebenfalls hilfreich, um sich zu merken, wie Slices funktionieren:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Eine Möglichkeit, sich die Funktionsweise von Slices zu merken, besteht darin, sich die Indizes als zwischen den Zeichen stehend vorzustellen, wobei der linke Rand des ersten Zeichens mit 0 nummeriert ist. Dann hat der rechte Rand des letzten Zeichens einer Kette von n Zeichen den Index n.
Aufzählung der Möglichkeiten, die die Grammatik zulässt:
>>> seq[:] # [seq[0], seq[1], ..., seq[-1] ]
>>> seq[low:] # [seq[low], seq[low+1], ..., seq[-1] ]
>>> seq[:high] # [seq[0], seq[1], ..., seq[high-1]]
>>> seq[low:high] # [seq[low], seq[low+1], ..., seq[high-1]]
>>> seq[::stride] # [seq[0], seq[stride], ..., seq[-1] ]
>>> seq[low::stride] # [seq[low], seq[low+stride], ..., seq[-1] ]
>>> seq[:high:stride] # [seq[0], seq[stride], ..., seq[high-1]]
>>> seq[low:high:stride] # [seq[low], seq[low+stride], ..., seq[high-1]]
Natürlich, wenn (high-low)%stride != 0
, dann wird der Endpunkt ein wenig niedriger als high-1
sein.
Wenn stride
negativ ist, wird die Reihenfolge ein wenig geändert, da wir abwärts zählen:
>>> seq[::-stride] # [seq[-1], seq[-1-stride], ..., seq[0] ]
>>> seq[high::-stride] # [seq[high], seq[high-stride], ..., seq[0] ]
>>> seq[:low:-stride] # [seq[-1], seq[-1-stride], ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]
Erweiterte Slicings (mit Kommas und Ellipsen) werden meist nur von speziellen Datenstrukturen (wie NumPy) verwendet; die Grundsequenzen unterstützen sie nicht.
>>> class slicee:
... def __getitem__(self, item):
... return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'