python: range

range 对象是(rangeobject) Python 内置的对象,它可以认为是一个不可变的数字序列,通常用于在 for 循环中指定循环的次数。虽然被称为函数,但 range 实际上是一个不可变的序列类型。

相比常规 list 或 tuple,range 对象总是占用固定数量的(较小)内存,不论其所表示的范围有多大,因为它只保存了 start、stop 和 step 值,并会根据需要计算具体单项或子范围的值。

快速使用

# 定义 range 对象
r = range(4)
r
# range(0, 4)

# 展开方法
[i for i in range(4)]
list(r)
[*r]
# [0, 1, 2, 3]
tuple(r)
# (0, 1, 2, 3)

# 定义示例
range(4) # [0, 1, 2, 3]
range(0, 4) # [0, 1, 2, 3]
range(2, 6) # [2, 3, 4, 5]
range(2, 10, 3) # [2, 5, 8]

# 负数
range(-10, 10, 5) # [-10, -5, 0, 5]
range(10, 1, -2) # [10, 8, 6, 4, 2]
range(1, 10, -1) # []

# 展开方法

语法

语法形式有两种:

range(stop)range(start, stop[, step])

该函数需要三个参数

  • 1.起始位置(可以省略,默认是0)
  • 2.结束位置(必须)
  • 3.步长(可以省略,默认是1)

参数说明

  • 以上三个参数必须是整数(integers),或者内置 int 类型,以及任何实现 __index__() 特殊方法的对象
  • 如果步长为零,则会引发 ValueError

生成规划

  • 如果 step 为正值,确定 range r 内容的公式为 r[i] = start + step*i 其中 i >= 0 且 r[i] < stop。
  • 如果 step 为负值,确定 range 内容的公式仍然为 r[i] = start + step*i,但限制条件改为 i >= 0 且 r[i] > stop。
  • 如果 r[0] 不符合值的限制条件,则该 range 对象为空。 range 对象确实支持负索引,但是会将其解读为从正索引所确定的序列的末尾开始索引。
  • 元素绝对值大于 sys.maxsize 的 range 对象是被允许的,但某些特性 (例如 len()) 可能引发 OverflowError。

属性和方法

range() 函数创建的 rangeobject,有三个属性和两个方法,不过相对使用较少。

# 定义范围对象 rangeobject
r = range(1, 10, 2)
list(r) # 转为列表
# [1, 3, 5, 7, 9]
  • 属性
# 属性
r.start # 1 开始值
r.stop # 10 终止值
r.step # 2 步长
  • 方法
# 返回值的出现次数
r.count(1) # 1
r.count(10) # 0

# 返回值的索引
r.index(3) # 1
# 如果该值不存在,则引发值错误
r.index(10) # ValueError: 10 is not in range

使用

可用列表推导式来展开 range 对象:

[i for i in range(4)] # [0, 1, 2, 3]

用在 for 循环中:

for i in range(2, 10, 2):
    print(i, end=' ')
# 4 6 8

var = 'hello'
for i in range(len(var)):
    print(var[i])

相关操作

range 对象实现了 collections.abc.Sequence 抽象基类(ABC),提供如包含检测、元素索引查找、切片等特性,并支持负索引。

from collections import abc

isinstance(r, abc.Sequence)
# True

type(r)
# range

issubclass(range, abc.Sequence)
# True

range 对象实现了 一般 序列的所有操作,但拼接和重复除外(这是由于 range 对象只能表示符合严格模式的序列,而重复和拼接通常都会违反这样的模式)。

r = range(0, 20, 2)
r
# range(0, 20, 2)
list(r)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
len(r)
# 10
max(r)
# 18
sum(r)
# 90
iter(r)
# <range_iterator at 0x7f9b3a7ad4a0>
11 in r
# False
10 in r
# True
r.index(10)
# 5
r[5]
# 10
r[:5]
# range(0, 10, 2)
r[-1]
# 18

不支持拼接和重复:

r + [1,2]
# TypeError: unsupported operand type(s) for +: 'range' and 'list'

r + r
# TypeError: unsupported operand type(s) for +: 'range' and 'range'

r*3
# TypeError: unsupported operand type(s) for *: 'range' and 'int'

使用 ==!= 检测 range 对象是否相等是将其作为序列来比较。 也就是说,如果两个 range 对象表示相同的值序列就认为它们是相等的。 (请注意比较结果相等的两个 range 对象可能会具有不同的 start, stop 和 step 属性,例如 range(0) == range(2, 1, 3) 而 range(0, 3, 2) == range(0, 4, 2)。)

版本变化

主要有:

  • 在 3.2 版更改: 实现 Sequence ABC。 支持切片和负数索引。 使用 int 对象在固定时间内进行成员检测,而不是逐一迭代所有项。
  • 在 3.3 版更改: 定义 ‘==’ 和 ‘!=’ 以根据 range 对象所定义的值序列来进行比较(而不是根据对象的标识)。
  • 在3.3 新版功能: start, stop 和 step 属性。

其他

range 对象的步长只能为整型,但实际需求中可能需要浮点型,可以考虑 numpy.linspace

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值