为什么不能使用范围对象来索引列表?

Why can't a range object be used to index a list?

在Python 3.9 中,无法使用范围对象来索引列表。 事实上 运行 下面的代码,第二个打印将 return 一个错误,指出“类型错误:列表索引必须是整数或切片,而不是范围”。

x = [1, 2, 3]
s = slice(3)
r = range(3)

print(x[s]) # ok
print(x[r]) # error

这是为什么? Python 解释器不能直接将范围转换为引擎盖下的切片,并将其用于索引吗? 这是因为某些根本原因,还是开发人员尚未实施(尚未实施?)?

有趣的是,确实可以使用范围索引 numpy 数组!

range() 确实不是列表也不是元组。它不适合切片。

它实现了 class collections.abc.Sequence。它只在内存中保存startstopstep,这对内存管理非常有用。这里的权衡是您不能执行您可以在列表上执行的所有操作,例如切片。但是您可以像这样轻松地将 range() 转换为 listlist(range(5)).

您可能需要阅读更多文档 here

A slicerange 是微妙的不同,尽管它们都使用 start, stop, step 三元组。如果 Python 默默地使用一个代替另一个,可能会导致细微的错误。


要直接查看差异,确实可以查看 numpy 两者导致不同索引的地方:

>>> arr = np.array([0, 1, 2, 3, 4])
>>> arr[slice(1, -1)]
array([1, 2, 3])
>>> arr[range(1, -1)]
array([], dtype=int64)

结果不同,因为slicerange对负数的意义不同

  • 一个range表示整数number line的一部分。这扩展到负数。
  • A slice 表示序列的 ordinal numbers/ 索引的一部分。1 这会将负数换回到正数。

或者更简单地说,slice 的含义取决于序列的大小,而 range 则不然。因此,不小心用一个代替另一个是错误的。


1 从技术上讲,slice 表示 任何 概念的 start, stop, step。标准序列类型将其解释为数字索引。例如,slice 也可以表示图形的