Umkehren einer Liste mit Slice-Notation


79

im folgenden Beispiel:

foo = ['red', 'white', 'blue', 1, 2, 3]

Dabei foo[0:6:1]werden alle Elemente in foo gedruckt. Das foo[6:0:-1]1. oder 0. Element wird jedoch weggelassen.

>>> foo[6:0:-1]
[3, 2, 1, 'blue', 'white']

Ich verstehe, dass ich foo.reverse () oder foo [:: - 1] verwenden kann, um die Liste in umgekehrter Reihenfolge zu drucken, aber ich versuche zu verstehen, warum foo [6: 0: -1] nicht die gesamte Liste druckt ?


3
Beachten Sie auch die foo[7:None:-1]Möglichkeit :)
— tzot

1
Ich habe noch nie Python verwendet, bevor ich nur versucht habe, die Slice-Notation zu verstehen. Meine Frage ist, warum foo [6: 0: -1] keinen Indexfehler auslöst. Interessiert sich Python nicht dafür? weil der Index 6 im obigen Beispielarray nicht verfügbar ist.
— Mubashar

3
@MubasharAhmad Slicing indiziert nicht und gibt keinen Fehler aus, wenn die Grenzen überschritten werden. Die Indizierung löst jedoch Ausnahmen aus, wenn sie außerhalb der Grenzen liegt.
— Huggie

Antworten:


151

Kurznotiz:

[ <first element to include> : <first element to exclude> : <step> ]

Wenn Sie das erste Element beim Umkehren einer Liste einschließen möchten, lassen Sie das mittlere Element wie folgt leer:

foo[::-1]

Hier finden Sie auch einige gute Informationen zu Python-Slices im Allgemeinen:
Erläutern Sie die Slice-Notation von Python


42
Dies: [ <first element to include> : <first element to exclude> : <step> ]ist die klarste Erklärung für die Slice-Syntax, die ich gesehen habe. Wenn man es "erstes auszuschließendes Element" nennt, wird wirklich klar, was los ist.
— Schof

Was ist mit negativem Schneiden mit negativen Schritten? Ich verstehe es immer noch nicht.
— Huggie

6
Wenn Sie einen negativen Index entweder als <first element to include>oder als Index <first element to exclude>am Ende der Liste verwenden, -1ist dies auch das letzte Element, -2das vorletzte Element usw. So x[-1:-4:-1]würden beispielsweise die letzten drei Elemente xin umgekehrter Reihenfolge abgerufen. Sie können dies also so interpretieren, dass Sie "rückwärts gehen und jedes Element ( -1Schritt) vom letzten Element in der Liste ( -1 <first element to include>) bis zum vierten Element vom Ende ( -4 <first element to include>) nehmen, aber nicht einbeziehen ".
— Andrew Clark

1
Beim Umkehren (dh wenn <step>ja -1) hilft es mir zu denken <first element to include, moving from right to left>. So erhalten Sie die nElemente "ganz links" aus einer Liste in umgekehrter Reihenfolge : foo[n-1::-1]. So erhalten Sie die nElemente "ganz rechts" in umgekehrter Reihenfolge : foo[-1:-n-1:-1].
— DJVG

1
Wie macht man das erste Element, das "das Element vorher foo[0]" ausschließt?
— BallpointBen

9

Wenn Sie Probleme haben, sich an die Slice-Notation zu erinnern, können Sie versuchen, den Hokey Cokey auszuführen :

[ In : Out : Schütteln Sie alles über ]

[Erstes Element in clude: Erstes Element zu verlassen out : Der Schritt zur Verwendung]

YMMV


7

... warum druckt foo [6: 0: -1] nicht die gesamte Liste?

Weil der Mittelwert eher der exklusive als der inklusive Stoppwert ist. Die Intervallnotation lautet [Start, Stopp].

Genau so funktioniert der [x] -Bereich:

>>> range(6, 0, -1)
[6, 5, 4, 3, 2, 1]

Dies sind die Indizes, die in Ihre resultierende Liste aufgenommen werden, und sie enthalten keine 0 für das erste Element.

>>> range(6, -1, -1)
[6, 5, 4, 3, 2, 1, 0]

Eine andere Sichtweise ist:

>>> L = ['red', 'white', 'blue', 1, 2, 3]
>>> L[0:6:1]
['red', 'white', 'blue', 1, 2, 3]
>>> len(L)
6
>>> L[5]
3
>>> L[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Der Index 6 liegt jenseits (genau eins) der gültigen Indizes für L und schließt ihn daher als ausgeschlossenen Stoppwert aus dem Bereich aus:

>>> range(0, 6, 1)
[0, 1, 2, 3, 4, 5]

Gibt Ihnen weiterhin Indizes für jedes Element in der Liste.


1
rangekann es, aber Slice kann es nicht, weil -1es das letzte Element ist. Also l=[1, 2, 3], l[2:-1:-1] == [].
— Simin Jie

6

Diese Antwort mag etwas veraltet sein, aber sie könnte für jemanden hilfreich sein, der an demselben Problem festhält. Sie können eine umgekehrte Liste mit einem beliebigen Ende erhalten - bis zu 0 Index, indem Sie das zweite In-Place-Slice wie folgt anwenden:

>>> L = list(range(10))
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (start_ex, end) = (7, 0)
>>> L[end:start_ex][::-1]
[6, 5, 4, 3, 2, 1, 0]

1
Dies ist eigentlich ziemlich nützlich, da Sie für alle Fälle die gleiche Syntax verwenden können. Sie müssen 0 nicht als Sonderfall behandeln.
— Tom Zych

Dies ist sinnvoller als das Standardverhalten von Python / numpy für negatives Schneiden, da normalerweise ein Bild oder ein Tensor, der an einer bestimmten Kante ausgerichtet ist, geschnitten und / oder umgekehrt werden soll, während Python / numpy die letzte Zeile / Spalte der Daten o_O verlieren.
— Dwayne Robinson

1

Verwenden

>>>foo[::-1]

Dies zeigt die Umkehrung der Liste vom Endelement bis zum Start an.


1

Sie können es zum Laufen bringen, wenn Sie einen negativen Stoppwert verwenden. Versuche dies:

foo[-1:-7:-1]

0

Ergänzen. Schritt um 2 umkehren:

A = [1,2,2,3,3]
n = len(A)
res = [None] * n
mid = n//2 + 1 if n%2 == 1 else n//2

res[0::2] = A[0:mid][::-1]
res[1::2] = A[0:mid][::-1]
print(res)

[2, 3, 2, 3, 1]


0

Die Antwort von Andrew Clark ein bisschen mehr formalisieren :

Angenommen, die Liste vund das v[n1:n2:n3]Slice. n1ist Anfangsposition, n2ist Endposition und n3ist Schritt

Schreiben wir einen Pseucode auf Python-Weise:

n3 = 1  if (n3 is missing) else n3
if n3==0:
   raise exception # error, undefined step

Erster Teil: n3 positiv

if n3>0:
   slice direction is from left to right, the most common direction         

   n1 is left slice position in `v` 
   if n1 is missing: 
      n1 = 0   # initial position
   if n1>=0:
      n1 is a normal position
   else: 
     (-n1-1) is the position in the list from right to left 

   n2 is right slice position in `v` 
   if n2 is missing: 
      n2 = len(x)  # after final position
   if n2>=0:
      n2 is a normal final position (exclusive)
   else: 
      -n2-1 é the final position in the list from right to left 
       (exclusive)

Zweiter Teil: n3 negativ

else: 
  slice direction is from right to left (inverse direction)

  n1 is right slice position in `v` 
  if n1 is missing: 
     n1 = -1   # final position is last position in the list.
  if n1>=0:
     n1 is a normal position
  else: 
     (-n1-1) is the position in the list from right to left 

  n2 is  left slice position in `v` 
  if n2 is missing: 
     n2 = -len(x)-1   # before 1st character  (exclusive)
  if n2>=0:
     n2 is a normal final position (exclusive)
  else: 
     -n2-1 is the ending position in the list from right to left 
     (exclusive)

Nun das ursprüngliche Problem: Wie kann man eine Liste mit Slice-Notation umkehren?

L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(L(::-1)) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Warum?
n1 is missing and n3<0 => n1=0
n2 is missing and n3<0 => n2 = -len(x)-1

Damit L(::-1) == L(-1:-11:-1)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.