为什么您可以对列表进行切片,使其超出总索引数,却无法直接检索该索引?

时间:2018-12-12 07:35:01

标签: python python-3.x list indexing slice

好的,我确定这个问题有点琐碎,但我很好奇!

在python中,这样做完全合法:

a = [1,2,3,4,5]
print(a[:123])

>> [1, 2, 3, 4, 5]

但是一旦您尝试这样做:

a = [1,2,3,4,5]
print(a[123])

>> IndexError: list index out of range

在将其存储在内存中并由编译器解释的上下文中,为什么会这样呢?

我尝试将第一个示例存储在变量中并检查该变量的长度,但这只是原始列表的长度,而忽略了随后的空白位置。

我真的很好奇,很想知道答案是什么!

3 个答案:

答案 0 :(得分:0)

Python 3.x中切片的语法如下,

CREATE TABLE Orders
(
   OrderNum      NUMBER (4) PRIMARY KEY,
   OrderDate     DATE,
   CustID        CHAR (3),
   PNum          VARCHAR2 (3),
   UnitPrice     NUMBER,
   QtyOrder      NUMBER,
   TotalCost     NUMBER,
   ShipDate      DATE,
   QtyShipped    NUMBER,
   OrderStatus   VARCHAR2 (10),
   ReasonNum     NUMBER,
   CONSTRAINT fk_CustID FOREIGN KEY (CustID) REFERENCES Customer (CustID),
   CONSTRAINT fk_PNum FOREIGN KEY (PNum) REFERENCES Product (PNum),
   CONSTRAINT fk_ReasonNum FOREIGN KEY
      (ReasonNum)
       REFERENCES CancelledOrder (ReasonNum)
);

您还可以通过其他方式使用切片,例如

a[start:end:step]

将'end'变量设置为大于列表长度的方法是可行的,因为无论您将'end'设置为什么,切片数组将始终以len(a)-1结尾 (或者在[[0],如果您将'step'设置为负数,则使分片返回数组反转)

回答为什么:列表切片会创建一个新列表。它从头开始复制到位置a[start:end] a[start:] a[:end] a[:] (不存在),这就是为什么它只切片到已知的末端。似乎python开发人员决定使切片更健壮,这意味着如果您提供的索引超出范围,则不会引发错误,相反,他们只是假设您希望将其扩展到列表的实际末尾。要绝对具体地确认该概念,您必须询问代码的维护者;)

答案 1 :(得分:0)

一个简单的答案将是在代码中处理。

切片时,如果提供的起始值或终止值大于列表的大小,则将被列表的最后一个索引覆盖。

当您寻找确切的索引时,它将在列表中找到索引,如果不存在,则会显示“索引超出范围”。

答案 2 :(得分:0)

这定义了包含5个元素的列表

a = [1,2,3,4,5]

这表明您需要从列表的开始到第124个索引

>> print(a[:123])
>> [1, 2, 3, 4, 5]

您正确地问为什么这不会引起分段错误或某些内存错误,因为此语句应该是非法的。没有第123或124索引。 这里的Python将从头开始,并继续进行迭代,直到出现以下任一情况:-

  1. 达到最大索引(123) OR
  2. 列表项用完

换句话说,如果您要求C走123步并且在5步之后有悬崖的边缘,C会跳下悬崖,而Python不会跳

如果是

print(a[123])

您不是从头开始迭代,而是要求直接跳至第123步。在这种情况下,C和Python都会因自己的哭声而崩溃(IndexError或Segmentation Fault)