2012-09-20 7 views
9

Von der Python-Dokumentation docs.python.org/tutorial/introduction.html#strings:Was sind die Standard-Slice-Indizes in Python * wirklich *?

Scheibe Indizes nützliche Standardwerte haben; Ein ausgelassener erster Index wird standardmäßig auf Null gesetzt, ein ausgelassener zweiter Index wird standardmäßig auf die Größe der zu schneidenden Zeichenfolge zurückgesetzt.

Für den Standardfall, macht dies durchaus Sinn:

>>> s = 'mystring' 
>>> s[1:] 
'ystring' 
>>> s[:3] 
'mys' 
>>> s[:-2] 
'mystri' 
>>> s[-1:] 
'g' 
>>> 

So weit, so gut. Allerdings scheint einen negativen Schrittwert mit leicht unterschiedlichen Vorgaben vorschlagen:

>>> s[:3:-1] 
'gnir' 
>>> s[0:3:-1] 
'' 
>>> s[2::-1] 
'sym' 

Gut, vielleicht, wenn der Schritt negativ ist, kehren sich die Standardwerte. Ein weggelassen erster Index standardmäßig auf die Größe der Zeichenfolge geschnitten wird, eine unterlassene zweiten Index standardmäßig auf Null:

>>> s[len(s):3:-1] 
'gnir' 

Sieht gut aus!

>>> s[2:0:-1] 
'sy' 

Whoops. Verpasste das "m".

Dann gibt es jedermanns Lieblings-String Reverse-Anweisung. Und süß ist:

>>> s[::-1] 
'gnirtsym' 

jedoch:

>>> s[len(s):0:-1] 
'gnirtsy' 

Die Scheibe enthält nie den Wert des zweiten Index in der Scheibe. Ich kann die Konsistenz sehen, es so zu machen.

Also ich denke, ich beginne zu verstehen, das Verhalten von Slice in seinen verschiedenen Permutationen. Ich habe jedoch das Gefühl, dass der zweite Index etwas Besonderes ist und dass der Standardwert des zweiten Index für einen negativen Schritt nicht tatsächlich in Form einer Zahl definiert werden kann.

Kann jeder prägnant die Standard-Slice-Indizes definieren, die für die bereitgestellten Beispiele verantwortlich sein können? Dokumentation wäre ein großes Plus.

+2

Ihr über dachte, es ... in Python Zeug nur "funktioniert": P –

+0

Wie gnibbler Punkte unten, manchmal Sie müssen wissen, wie es funktioniert. Wenn Sie zum Beispiel eine Funktion haben, die drei optionale Parameter und Slices basierend auf den Werten dieser Parameter verwendet, was sollte sie verwenden, wenn die Parameter weggelassen werden? – abarnert

+1

Ich wusste, dass ich ein wenig pendantisch war, aber manchmal möchte ich genau wissen, wie die Dinge funktionieren. Ich vertraue Magie nicht :-). – MikeG

Antwort

8

Es gibt eigentlich keine Standardwerte; Ausgelassene Werte werden speziell behandelt.

In jedem Fall werden ausgelassene Werte jedoch genau so behandelt wie None. Dies bedeutet, dass Sie, wenn Sie den Interpreter nicht hacken (oder die Module parser, ast usw. verwenden), einfach so vorgeben können, dass die Standardwerte None sind (wie rekursive Antwort sagt), und Sie erhalten immer die richtigen Antworten.

Die zitierte informelle Dokumentation ist nicht ganz genau - was für etwas sinnvoll ist, das Teil eines Tutorials sein soll. Für die echten Antworten müssen Sie sich an die Referenzdokumentation wenden.

Für 2.7.3, Sequence Types beschreibt in Noten 3, 4 Schneiden und 5.

Für [i:j]:

... Wenn i weggelassen oder None, verwenden 0. Wenn j weggelassen wird oder None, verwenden Sie len(s).

Und für [i:j:k]:

Wenn i oder j weggelassen oder None, sie werden „end“ Werte (die auf dem Schild von k Ende abhängt). Hinweis, k kann nicht Null sein.Wenn kNone ist, wird es wie 1 behandelt.

Für 3,3, Sequence Types hat genau die gleiche Formulierung wie 2.7.3.

+0

Natürlich muss ich mit den Python-Dokumenten vertrauter werden. – MikeG

+0

Der große Schlüssel ist zu wissen, wann zu überprüfen, ob Sie die Referenzdokumente betrachten oder nicht. Leider ist die "informelle Einführung" oft nicht sehr informell und liest sich wie Referenzdokumente - und zur gleichen Zeit ist die Referenzdokumentation glücklicherweise viel klarer als beispielsweise die ISO C++ Spezifikation - und so lese ich oft das Informelle docs und wundere mich über etwas, das nicht vollständig spezifiziert ist, bis ich dieses "Tutorial" in der URL sehe und das Problem herausfinden ... – abarnert

+0

Was sind diese Endwerte von 'i' und' j' in '[i: j: k]' für ein positives k und ein negatives k? –

4

die Hinweise in den reference documentation for sequence types erklären dies in einigen Einzelheiten:

(5.) Die Scheibe s von i zu j mit Schritt k wird als die Sequenz, definiert von Artikel mit Index x = i + n*k so dass 0 <= n < (j-i)/k. Mit anderen Worten sind die Indizes i, i+k, i+2*k, i+3*k und so weiter zu stoppen, wenn j erreicht ist (aber nie einschließlich j). Wenn i oder j größer als len(s) ist, verwenden Sie len(s). Wenn i oder j weggelassen werden oder None, werden sie zu "End" -Werten (deren Ende vom Vorzeichen k abhängt).Hinweis, k kann nicht Null sein. Wenn kNone ist, wird es wie 1 behandelt.

So können Sie das folgende Verhalten erhalten:

>>> s = "mystring" 
>>> s[2:None:-1] 
'sym' 
+0

In diesem Fall, was bedeutet "keiner"? Wenn es als obere Grenze in einem negativen Schritt verwendet wird? –

+0

Gibt es einen bestimmten ganzzahligen Index, der None als _upper bound_ ersetzt? 'None', wenn für die untere Grenze verwendet, wird ersetzt durch' len (s) - 1', aber welche obere Grenze wird verwendet, wenn'None', speziell für einen negativen Schritt? –

+0

@AsadMoosvi Der Wert von 'None' ist ein spezieller Wert, der keinen äquivalenten Ganzzahlwert hat. –

4

Ich habe keine Dokumentation, aber ich denke, die Standard-[None:None:None]

>>> "asdf"[None:None:None] 
'asdf' 
>>> "asdf"[None:None:-1] 
'fdsa' 
+1

Dies ist nützlich, um zu wissen, ob Sie 'slice()' Objekte erstellen müssen, da Sie nicht einfach 'slice (,, -1)' sagen können. Es muss "slice (None, None, -1)" sein. –

+0

Tatsächlich sind die Standardwerte nicht None, aber ausgelassene Werte werden immer gleich behandelt wie None. Also, wenn Sie den Interpreter hacken oder die Module parser/ast/compiler verwenden, ist das falsch, aber für jeden anderen Zweck ist es richtig. – abarnert

+0

@abarnert ..aber zumindest, wenn '__getitem__' durch Slicing aufgerufen wird, haben die ausgelassenen Felder den Wert' None'. – minmaxavg

1

Eigentlich logisch ist es ist ...

Wenn Sie sich den Endwert ansehen, zeigt er immer auf den Index nach dem letzten Index. Also, 0 als den Endwert verwenden, bedeutet, dass es bis Element bei Index 1 erhält. Also müssen Sie diesen Wert weglassen .. so, dass es die gewünschte Zeichenfolge zurückgibt.

>>> s = '' 
>>> s[0], s[:0] 
('0', '') 
>>> s[1], s[:1] 
('1', '0') 
>>> s[2], s[:2] 
('2', '01') 
>>> s[3], s[:3] 
('3', '012') 
>>> s[0], s[:0:-1] 
('0', '987654321') 
3

Der Wert Ende ist immer exklusive, so dass die 0 Endwert Mittel Index 1, aber nicht 0 Verwendung Keine statt (da negative Zahlen eine andere Bedeutung haben):

>>> s[len(s)-1:None:-1] 
'gnirtsym' 

Hinweis der Startwert ebenfalls; der letzte Zeichenindex ist len(s) - 1; Sie können auch die buchstabieren als -1 (als negative Zahlen in Bezug auf die Länge interpretiert werden):

>>> s[-1:None:-1] 
'gnirtsym' 
+0

Ich bin wirklich verwirrt über die obere Grenze, wenn ein negativer Schritt verwendet wird. Was bedeutet eine Obergrenze von "None", wenn der Schritt "-1" bedeutet? 's [-1: -len (s) -1: -1]' gibt auch eine umgekehrte Zeichenfolge zurück. Ist also die Obergrenze von 'None' durch' -len (s) -1' ersetzt? Was ich versuche zu verstehen, ist ... wird die obere Grenze von 'None' durch einen bestimmten ganzzahligen Index ersetzt, wenn ein negativer Schritt verwendet wird? –

+0

@AsadMoosvi: Für die Start- und Stopppositionen sind die Standardwerte der Anfang und das Ende der Sequenz * in Iterationsrichtung *. Für negative Schritte ist start das Ende der Sequenz und stop ist hinter '0' (aber Sie können nicht '-1' angeben, da negative Werte von der Länge vor der Verwendung subtrahiert werden. Deshalb müssen Sie '' verwenden -len (-1), um das zu machen, für den spezifischen Wert in meiner Antwort ist das "-8 - 1" == "-9" und das wird dann relativ zur Länge "8" verwendet, so dass du mit " -1 'als Stop-Wert am Ende. Viel mühsamer als nur 'None' zu ​​verwenden. –

+0

Aber '-len (s) -1' ist ein negativer Wert an sich. Sollte es nicht von der Länge abgezogen werden, wenn es benutzt wird? –

0

Gut zu wissen, wenn Sie __getslice__ implementieren: j standardmäßig sys.maxsize (https://docs.python.org/2/reference/datamodel.html#object.getslice)

>>> class x(str): 
... def __getslice__(self, i, j): 
...  print i 
...  print j 
... 
... def __getitem__(self, key): 
...  print repr(key) 
... 
>>> x()[:] 
0 
9223372036854775807 
>>> x()[::] 
slice(None, None, None) 
>>> x()[::1] 
slice(None, None, 1) 
>>> x()[:1:] 
slice(None, 1, None) 
>>> import sys 
>>> sys.maxsize 
9223372036854775807L 
Verwandte Themen