Es ist eine bekannte Geschichte (ich vergesse oft), dass unabhängig davon, wie groß oder klein eine Zahl in einem Python-Slice angegeben ist, kein Indexfehler auftritt, aber der Grund ist "** Es behandelt es intern gut. ** ”Ich dachte, ich könnte keinen Artikel auf Japanisch finden, der das oben Genannte erklärt, und beschloss, ihn als Lückenindustrie zu schreiben.
In diesem Artikel werde ich das Thema des Themas aus zwei Perspektiven erläutern: ** Idee ** und ** Umsetzung . Ich hoffe, die Krankheit von Leuten loszuwerden, die Python noch nicht kennen und das Gefühl haben, dass " Indexfehler beim Extrahieren eines bestimmten Elements May als Slice bezeichnet wird, aber nicht als Slice **". Ich werde.
Da der Autor selbst unerfahren ist, würde ich es auch begrüßen, wenn Sie auf Ungenauigkeiten in den Ausdrücken für ein späteres Studium hinweisen könnten.
Dieser Abschnitt entspricht dem Ideenteil des Schneidens. Selbst im offiziellen Dokument ist "Was ist ein Slice?" Nicht einfach und klar geschrieben (sieht so aus), aber es ist frustrierend, aber vorerst gibt es die folgende Erklärung.
--Hinweis zu s [i: j]
Eine Schicht von> s von i bis j ist als eine Folge von Elementen mit einem Index k definiert, so dass i <= k <j ist.
--Hinweis zu s [i: j: k]
Das> s "Slice von i nach j mit den Schritten k" besteht aus Elementen mit einem Index x = i + n * k (wobei n eine beliebige ganze Zahl ist, die 0 <= n <(ji) / k erfüllt). Als Sequenz definiert.
Integrierte Dokumentation zu Python 3.8.5
Sie können es verstehen, wenn Sie es richtig lesen, aber es fühlt sich ein wenig nervig an.
Wenn Sie nur die Teile extrahieren, die Sie jetzt benötigen, bedeutet das Schneiden, dass "eine neue ** Sequenz ** aus ** Elementen ** erstellt wird, die dem angegebenen Index ** aus der ursprünglichen Sequenz entsprechen"?
(Eine Sequenz ist ein Datentyp wie Liste, Taple, Bereich, Zeichenfolge, Bytezeichenfolge usw.)
Hier ist ein Zitat von Stack Overflow, warum dies wichtig ist.
Indexing returns a single item, but slicing returns a subsequence of items. So when you try to index a nonexistent value, there's nothing to return. But when you slice a sequence outside of bounds, you can still return an empty sequence.
https://stackoverflow.com/a/9490148
Mit anderen Worten
Ich sage das. Ich habe oben 1 erwähnt, daher denke ich nicht, dass es notwendig ist, es zu erklären, aber was ist mit 2?
Kurz gesagt, [0,1,2] [3]
ist ** ein Fehler, da es keinen Rückgabewert ** gibt, aber [0,1,2] [3:]
ist ein Element, das Index 3 oder höher entspricht. Wenn keine ** leere Liste vorhanden ist, kann [[] `als Rückgabewert zurückgegeben werden, sodass kein Fehler ** erforderlich ist.
Das heißt, die Antoinette-Leute (einschließlich des Autors), die dies lesen, sagten: "** Wenn Sie einen Rückgabewert haben müssen, können Sie None mit" [0,1,2] [3] "zurückgeben. Sie könnten denken, "Es ist nicht gut **".
In diesem Fall ist es jedoch möglich zu bestimmen, ob ** [0,1,2] [3]
None zurückgibt oder [0,1,2, None] [3]
None zurückgibt ** Ich brauche immer noch einen Indexfehler, weil er schwieriger wird (und ihn freundlicherweise in der Fortsetzung des vorherigen Zitats ergänzt).
Die Erklärung mag etwas redundant gewesen sein, aber die Schlussfolgerung war, dass der Fehler "** Slice kann eine leere Sequenz zurückgeben, auch wenn kein entsprechendes Element ** vorhanden ist" nicht auftritt.
(Jabashi: Ich möchte Begriffe wie "Teilmenge / Teilzeichenfolge" und "leere Menge" verwenden, aber wenn ich "Menge" sage, ignoriere ich das Element des Sequenztyps "Reihenfolge". Schließlich bleibt nichts anderes übrig, als es wie das offizielle Dokument zu erklären.)
Dieser Abschnitt entspricht dem Implementierungsteil des Slice.
Wie gehen Sie mit Operationen wie "[P, y, t, h, o, n] [100: 200]" auf "gute Weise" um? Die Antwort ist eine Fortsetzung des Zitats aus dem offiziellen Dokument im vorherigen Abschnitt. Es ist im Teil versteckt.
--Hinweis zu s [i: j]
Wenn> i oder j größer als len (s) ist, verwenden Sie len (s). Wenn i weggelassen wird oder Keine, verwenden Sie 0. Wenn j weggelassen wird oder Keine, verwenden Sie len (s). Wenn i größer oder gleich j ist, ist das Slice eine leere Sequenz.
Mit anderen Worten, in "[P, y, t, h, o, n] [100: 200]" wird "len (s)" verwendet, weil sowohl "i" als auch "j" größer als "len (s)" sind. Dann gilt "i (= len (s))> = j (= len (s))", so dass beurteilt wird, dass eine leere Sequenz zurückgegeben wird.
[Slices werden auch intern indiziert](https://qiita.com/tanuk1647/items/276d2be36f5abb8ea52e#How Slices werden in Indizes konvertiert), daher sind sie größer als "len (s)" Die Zahlen werden im Voraus umgerechnet. Wenn Sie "Schritt" angeben, wird im Grunde die gleiche Verarbeitung ausgeführt.
Abschließend werde ich Ihnen einen Hinweis geben, wie die Verarbeitung hier in CPython implementiert ist. Ich bin auch nicht stark in C, daher denke ich, dass Sie es in dem Maße betrachten sollten, dass "Ah, es ist definitiv so geschrieben" (auch im Quellcode / * ist es schwieriger, es richtig zu machen, als Sie vielleicht könnten). Es heißt denken * /
).
(In diesem Abschnitt haben wir den Fall erklärt, in dem "Schritt" nicht verwendet wird, aber im Anführungszeichen ist es der Prozess, in dem "Schritt" verwendet wird. Ich weiß es nicht.)
sliceobject.c
defstop = *step < 0 ? -1 : length;
...
if (r->stop == Py_None) {
*stop = defstop;
}
...
if ((*step < 0 && *stop >= *start)
|| (*step > 0 && *start >= *stop)) {
*slicelength = 0;
cpython: 3a1db0d2747e Objects/sliceobject.c
Das Schneiden ist bequem.
Danke, dass du bis zum Ende zugesehen hast.
Integrierte Dokumentation zu Python 3.8.5 [Python] Zusammenfassung der Schneidevorgänge --Qiita python - Why does substring slicing with index out of range work? - Stack Overflow string - Why python's list slicing doesn't produce index out of bound error? - Stack Overflow
Recommended Posts