为什么不能使用范围对象来索引列表?
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。它只在内存中保存start
、stop
和step
,这对内存管理非常有用。这里的权衡是您不能执行您可以在列表上执行的所有操作,例如切片。但是您可以像这样轻松地将 range()
转换为 list
:list(range(5))
.
您可能需要阅读更多文档 here。
A slice
和 range
是微妙的不同,尽管它们都使用 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)
结果不同,因为slice
和range
对负数的意义不同
- 一个
range
表示整数number line的一部分。这扩展到负数。
- A
slice
表示序列的 ordinal numbers/ 索引的一部分。1 这会将负数换回到正数。
或者更简单地说,slice
的含义取决于序列的大小,而 range
则不然。因此,不小心用一个代替另一个是错误的。
1 从技术上讲,slice
表示 任何 概念的 start, stop, step
。标准序列类型将其解释为数字索引。例如,slice
也可以表示图形的 边 。
在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。它只在内存中保存start
、stop
和step
,这对内存管理非常有用。这里的权衡是您不能执行您可以在列表上执行的所有操作,例如切片。但是您可以像这样轻松地将 range()
转换为 list
:list(range(5))
.
您可能需要阅读更多文档 here。
A slice
和 range
是微妙的不同,尽管它们都使用 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)
结果不同,因为slice
和range
对负数的意义不同
- 一个
range
表示整数number line的一部分。这扩展到负数。 - A
slice
表示序列的 ordinal numbers/ 索引的一部分。1 这会将负数换回到正数。
或者更简单地说,slice
的含义取决于序列的大小,而 range
则不然。因此,不小心用一个代替另一个是错误的。
1 从技术上讲,slice
表示 任何 概念的 start, stop, step
。标准序列类型将其解释为数字索引。例如,slice
也可以表示图形的 边 。