Antworten:
es bedeutet "nichts für das erste Argument, nichts für das zweite und springe um drei". Es wird jedes dritte Element der Sequenz in Scheiben geschnitten. Erweiterte Scheiben ist das, was Sie wollen. Neu in Python 2.3
range(10)[::3]
Ausgaben[0, 3, 6, 9]
::
wie [n ::] vorher kommt ? Was bedeutet es also n
?
seq[::n]
ist eine Folge jedes n
-ten Elements in der gesamten Folge.
Beispiel:
>>> range(10)[::2]
[0, 2, 4, 6, 8]
Die Syntax lautet:
seq[start:end:step]
So können Sie tun:
>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]
s[i:j:k]
ist laut Dokumentation "Scheibe von s von i nach j mit Schritt k". Wenn i
und j
fehlen, wird die gesamte Sequenz angenommen und s[::k]
bedeutet somit "jedes k-te Element".
Lassen Sie uns zunächst eine Liste initialisieren:
>>> s = range(20)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Nehmen wir jeden dritten Gegenstand aus s
:
>>> s[::3]
[0, 3, 6, 9, 12, 15, 18]
Nehmen wir jeden dritten Gegenstand aus s[2:]
:
>>> s[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> s[2::3]
[2, 5, 8, 11, 14, 17]
Nehmen wir jeden dritten Gegenstand aus s[5:12]
:
>>> s[5:12]
[5, 6, 7, 8, 9, 10, 11]
>>> s[5:12:3]
[5, 8, 11]
Nehmen wir jeden dritten Gegenstand aus s[:10]
:
>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]
Dieses visuelle Beispiel zeigt Ihnen, wie Sie Elemente in einer NumPy-Matrix (zweidimensionales Array) auf unterhaltsame Weise ordentlich auswählen (ich verspreche es). Schritt 2 unten veranschaulicht die Verwendung dieses ::
fraglichen "Doppelpunkts" .
(Achtung: Dies ist ein NumPy-Array-spezifisches Beispiel mit dem Ziel, den Anwendungsfall von "Doppelpunkt" ::
für das Springen von Elementen in mehreren Achsen zu veranschaulichen . Dieses Beispiel behandelt keine nativen Python-Datenstrukturen wie List
).
Angenommen, wir haben eine NumPy-Matrix, die folgendermaßen aussieht:
In [1]: import numpy as np
In [2]: X = np.arange(100).reshape(10,10)
In [3]: X
Out[3]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
Sagen Sie aus irgendeinem Grund, Ihr Chef möchte, dass Sie die folgenden Elemente auswählen:
"Aber wie ???" ... Lesen Sie weiter! (Wir können dies in einem 2-Schritt-Ansatz tun)
Geben Sie den "Startindex" und den "Endindex" in zeilen- und spaltenweiser Richtung an.
In Code:
In [5]: X2 = X[2:9,3:8]
In [6]: X2
Out[6]:
array([[23, 24, 25, 26, 27],
[33, 34, 35, 36, 37],
[43, 44, 45, 46, 47],
[53, 54, 55, 56, 57],
[63, 64, 65, 66, 67],
[73, 74, 75, 76, 77],
[83, 84, 85, 86, 87]])
Beachten Sie, dass wir gerade unsere Teilmenge mithilfe der einfachen Start- und Endindizierungstechnik erhalten haben. Als nächstes, wie man das "Springen" macht ... (lesen Sie weiter!)
Wir können nun die "Sprungschritte" sowohl in zeilen- als auch in spaltenweiser Richtung angeben (um Elemente auf "springende" Weise auszuwählen):
Im Code (beachten Sie die Doppelpunkte):
In [7]: X3 = X2[::3, ::2]
In [8]: X3
Out[8]:
array([[23, 25, 27],
[53, 55, 57],
[83, 85, 87]])
Wir haben gerade alle Elemente nach Bedarf ausgewählt! :) :)
Jetzt, da wir das Konzept kennen, können wir Schritt 1 und Schritt 2 einfach zu einem konsolidierten Schritt kombinieren - für Kompaktheit:
In [9]: X4 = X[2:9,3:8][::3,::2]
In [10]: X4
Out[10]:
array([[23, 25, 27],
[53, 55, 57],
[83, 85, 87]])
Getan!
X[2:9,3:8][::3,::2] = 0
(um die markierten Einträge durch 0 zu ersetzen). Wenn Sie X
erneut eingeben, werden alle markierten Einträge auf gesetzt 0
.
Beim Schneiden in Python ist der dritte Parameter der Schritt. Wie bereits erwähnt, finden Sie unter Erweiterte Slices eine schöne Übersicht.
Mit diesem Wissen [::3]
bedeutet dies nur, dass Sie keine Start- oder Endindizes für Ihr Slice angegeben haben. Da Sie einen Schritt angegeben haben 3
, wird bei jedem dritten Eintrag something
mit dem ersten Index begonnen. Zum Beispiel:
>>> '123123123'[::3]
'111'
Sie können diese Notation auch in Ihren eigenen benutzerdefinierten Klassen verwenden, damit sie das tut, was Sie wollen
class C(object):
def __getitem__(self, k):
return k
# Single argument is passed directly.
assert C()[0] == 0
# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)
# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)
# If you omit any part of the slice notation, it becomes None.
assert C()[:] == slice(None, None, None)
assert C()[::] == slice(None, None, None)
assert C()[1::] == slice(1, None, None)
assert C()[:2:] == slice(None, 2, None)
assert C()[::3] == slice(None, None, 3)
# Tuple with a slice object:
assert C()[:, 1] == (slice(None, None, None), 1)
# Ellipsis class object.
assert C()[...] == Ellipsis
Wir können dann Slice-Objekte öffnen als:
s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3
Dies wird insbesondere in Numpy verwendet, um mehrdimensionale Arrays in jede Richtung zu schneiden.
Natürlich sollte jede vernünftige API ::3
mit der üblichen "alle 3" -Semantik verwendet werden.
Das Verwandte Ellipsis
wird weiter behandelt unter: Was macht das Ellipsis-Objekt?
Python verwendet das ::, um den End-, den Start- und den Step-Wert zu trennen.
[5::]
. Was bedeutet es also mit 5?