python 为什么使用切片表示法并将0作为“stop”来反转列表时,不返回整个列表?

v6ylcynt  于 2023-01-04  发布在  Python
关注(0)|答案(9)|浏览(155)

在以下示例中:

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

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

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

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

jljoyd4f

jljoyd4f1#

切片符号简而言之:

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

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

foo[::-1]

你也可以在这里找到一些关于Python切片的有用信息:
Explain Python's slice notation

pqwbnv8z

pqwbnv8z2#

如果您在记忆切片符号时遇到困难,可以尝试执行Hokey Cokey
[输入输出尽情摇摆
[的第一个元素包括:要省略的第一个元素:要使用的步骤]
YMMV公司

ugmeyewa

ugmeyewa3#

这个答案可能有点过时了,但是对于遇到同样问题的人来说可能会很有帮助。你可以得到一个任意的end-up to 0索引的reverse list,应用第二个in-place切片如下:

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

sqougxex4#

...为什么foo[6:0:-1]不打印整个列表?
因为中间值是 exclusive,而不是inclusive,停止值。间隔表示法是[start,stop)。
这正是[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]

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

ftf50wuq

ftf50wuq5#

这是一个非常好的问题,而且,在我看来,上面的答案没有一个真正回答了被问到的问题。部分原因是一个理智上诚实的答案可能揭示了Python类型系统的一个弱点。同样的弱点也存在于其他一些语言中。
一个更理智诚实的回答可能是:Python切片不能很好地泛化。
确切地说,我们可以用collection[begin:end]在一个方向上遍历集合,但是collection[end:begin:-1]不起作用,因为第一个索引是0,但是“第一个索引之前的索引”不是-1,因此collection[end:-1:-1]的计算结果不是我们所期望的。
[first to include : first to exclude : step]的解释是有缺陷的,如果“first to exclude”是第一个元素之前的那个元素,那么您就不能像在希望包含同一个第一个元素的情况下那样表达它。
总而言之,你期望通用性并不疯狂,它只是不存在。

dffbzjpn

dffbzjpn6#

如果使用负停止值,则可以使其工作。尝试以下操作:

foo[-1:-7:-1]
kknvjkwl

kknvjkwl7#

用途

>>>foo[::-1]

这将显示从结束元素到开始元素的列表反转,

uttx8gqw

uttx8gqw8#

补.倒步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)

[二、三、二、三、一]

r8uurelv

r8uurelv9#

再把andrew-clark的答案形式化一点:
假设列表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]

为什么?

  • =〉*
  • =〉*
    所以L(::-1) == L(-1:-11:-1)

相关问题