使用切片符号反转列表


79

在以下示例中:

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

其中:foo[0:6:1]将打印foo中的所有元素。但是,foo[6:0:-1]将省略第一个或第0个元素。

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

我了解我可以使用foo.reverse()或foo [::-1]反向打印列表,但是我想了解为什么foo [6:0:-1]不能打印整个列表?


3
还请注意foo[7:None:-1]可能性:)
tzot 2011年

1
我在尝试理解切片符号之前从未使用过python,我的问题是为什么foo [6:0:-1]不会抛出索引错误,python不在乎吗?因为上面的示例数组中6索引不可用。
穆巴沙尔

3
@MubasharAhmad切片未建立索引,并且在超出范围时不会抛出任何错误。但是,索引超出范围时确实会引发异常。
huggie 2014年

Answers:


151

切片符号简而言之:

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

如果要在反转列表时包括第一个元素,则将中间元素留空,如下所示:

foo[::-1]

您还可以在这里找到有关Python切片的一些很好的信息:
解释Python的切片符号


42
[ <first element to include> : <first element to exclude> : <step> ]是我见过的slice语法的最清晰的解释。将其称为“要排除的第一个元素”确实使事情变得显而易见。
舒夫2011年

负片负片怎么办?我还是不明白。
huggie 2014年

6
当您使用负索引作为索引<first element to include><first element to exclude>从列表-1的末尾开始索引时,最后一个元素-2也是如此,倒数第二个元素也是如此,等等。例如,以相反的顺序x[-1:-4:-1]获取最后三个元素x。因此,您可以将其解释为“-1从列表(-1 <first element to include>)中的最后一个元素向后移动每个元素(步骤),直到但不包括末尾(-4 <first element to include>)的第四个元素”。
Andrew Clark

1
倒车时(即如果<step>-1),它有助于我思考<first element to include, moving from right to left>。因此,要n以相反的顺序从列表中获取“最左侧”的元素:foo[n-1::-1]。以n相反的顺序获取“最右边”的元素:foo[-1:-n-1:-1]
djvg

1
如何使第一个元素排除“之前的元素foo[0]”?
BallpointBen

9

如果您在记住切片符号时遇到麻烦,可以尝试使用Hokey Cokey

[摇一回事]

[第一元件CLUDE:第一元件离开:该步骤,以使用]

青年汽车


7

...为什么foo [6:0:-1]不显示整个列表?

因为中间值是排他性的,而不是包容,停止值。的间隔表示法是[开始,停止)。

这正是[x] range的工作方式:

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

这些是包含在结果列表中的索引,并且第一项不包括0。

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

另一种查看方式是:

>>> 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

索引6超出了L的有效索引(准确地说是一次),因此将其从该范围中排除为排除的停止值:

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

仍会为您提供列表中每个项目的索引。


1
range可以做到,但slice不能做到,因为这-1是最后一个元素。因此l=[1, 2, 3]l[2:-1:-1] == []
Simin Jie

6

这个答案可能有点过时了,但是对于那些遇到同样问题的人可能会有所帮助。您可以获取具有任意结尾的反向列表-索引最多为0,应用第二个就位切片,如下所示:

>>> 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
这实际上非常有用,因为您可以在所有情况下使用相同的语法。您不必将0视为特例。
Tom Zych '18

这比Python / numpy进行负切片的默认行为更有意义,因为通常情况下,它们要切片和/或反转与给定边对齐的图像或张量,而Python / numpy会丢失数据o_O的最后一行/列。
Dwayne Robinson


1

如果使用负停止值,则可以使其正常工作。试试这个:

foo[-1:-7:-1]

0

补充。逆转步骤2:

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

将来自安德鲁-克拉克的答案正式化一点:

假设列表vv[n1:n2:n3]切片。 n1是初始位置,n2是最终位置,n3是步骤

让我们以Python方式编写一些伪代码:

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

第一部分:n3正

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)

第二部分:n3负

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)

现在的原始问题是:如何使用切片符号反转列表?

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

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

所以 L(::-1) == L(-1:-11:-1)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.