Python range() 语法
range() 是 Python 的一个内置函数,它用于生成某个范围的数字序列。range() 函数最常见用于 for 循环 中。
语法:
range(start, stop, step)说明:
range() 函数接收以下 3 个参数。
start(可选,默认值:0):表示开始值(包含)。stop(必选):表示结束值(不包含)。step(可选,默认值:1):表示步长,即每两个数的间隔。步长不能为 0,否则会触发 ValueError 异常。
简单来说,range() 函数有以下 3 种取值情况。
- 当 range() 有 1 个参数时,表示 range() 只有结束值。也就是 range(stop),此时循环是从 0 开始的。
- 当 range() 有 2 个参数时,表示 range() 只有开始值和结束值。也就是 range(start, stop),此时循环是从 “开始值” 开始的。
- 当 range() 有 3 个参数时,表示 range() 有开始值、结束值和步长。所谓的步长,也叫 “间隔”,指的是每次循环后变量增加或减少的值。
总结一下,range() 函数有以下 3 种调用方式。
range(stop) → 等价于 range(0, stop, 1)
range(start, stop) → 等价于 range(start, stop, 1)
range(start, stop, step)注意:
- range() 函数返回的是一个可迭代对象,而不是一个列表。如果你想要得到一个列表,则需要使用 list() 函数将其转化为列表。
- 当 start 大于 stop 时,range() 函数仍然会返回一个数字序列。只不过该序列的元素是按照从 start 开始到 stop 结束,且以步长为负数的方向递减的。
- range 对象是惰性求值的,它不会立即生成所有数字并存储在内存中,而是在迭代时按需生成,这对于处理大范围数字非常高效。
Python range() 摘要
| 使用频率 | 极高 |
|---|---|
| 时间复杂度 | O(1)(创建 range 对象本身),O(N)(迭代 N 个元素时) |
| 空间复杂度 | O(1)(无论范围多大,都只存储 start、stop、step 三个值) |
| 官方文档 | 查看 |
| 相关函数 | zip()、enumerate() |
Python range() 示例
接下来,我们通过几个简单的例子来讲解一下 Python range() 函数是如何使用的。
示例 1:range() 带 1 个参数
for i in range(5):
print(i)运行结果如下。
0
1
2
3
4分析:
range(5) 表示循环的结束值为 5,从运行结果可以看出,结束值是不被包含进去的。只需要记住这一点就可以了:不管 range() 的参数是怎样的形式,结束值都不会被包含进去。
下面 3 种方式是等价的,小伙伴们可以思考一下为什么。
range(5)
range(0, 5)
range(0, 5, 1)示例 2:range() 带 2 个参数
for i in range(2, 5):
print(i)运行结果如下。
2
3
4分析:
range(2, 5) 表示循环的开始值为 2,结束值为 5,也就是取值范围为:[2, 5)。
示例 3:range() 设置步长(正数)
for i in range(0, 5, 2):
print(i)运行结果如下。
0
2
4分析:
range(0, 5, 2) 表示循环开始的值为 0,结束的值为 5,步长为 2。也就是说,每次循环,i 不再是加 1,而是加 2。
示例 4:range() 设置步长(负数)
for i in range(5, 0, -1):
print(i)运行结果如下。
5
4
3
2
1分析:
range(5, 0, -1) 表示循环开始的值为 5,结束的值为 0,步长为 -1。也就是说,每次循环,i 的值就减 1。使用这种方式,我们可以实现递减效果(类似于倒计时)。
提示: 变量的值每次只增加 1,这种行为被称为 “递增”。而变量的值每次只减少 1,这种行为被称为 “递减”。
示例 5:range() 的边界情况
print(list(range(5, 2)))
print(list(range(2, 5, -1)))
print(list(range(0, 5, -2)))运行结果如下。
[]
[]
[]分析:
如果 range() 的范围是无效范围,则会返回空序列。
range() 返回值
range() 函数返回的是一个可迭代对象,我们可以使用 list() 函数将其转换为一个列表。
示例 6:range() 返回可迭代对象
nums = range(5)
print(nums)
print(list(nums))运行结果如下。
range(0, 5)
[0, 1, 2, 3, 4]range() 最佳实践
在实际开发中,小伙伴们应该遵循以下最佳实践:
- 循环控制:优先使用 for i in range(n),而非 while 循环 进行确定次数的迭代。
- 内存优化:处理大范围时尽量保持 range 对象形态,避免转换为列表。
- 边界验证:使用前应该检查参数有效性,比如:
def safe_range(start, stop=None, step=1):
if stop is None:
start, stop = 0, start
if step == 0:
raise ValueError('range() 第3个参数不能为0')
return range(start, stop, step)常见问题
1. 为什么 range() 不包含结束值?
这种设计可以使得 range(n) 能直接生成 n 个元素(0 到 n-1),与列表索引规则一致。
2. 如何使得 range() 包含结束值?
我们可以调整结束值为 stop + 1,比如:
list(range(2, 6)) # 输出:[2, 3, 4, 5]
list(range(2, 6+1)) # 输出:[2, 3, 4, 5, 6]3. range() 与列表两者的性能差异?
range 对象在迭代时动态生成值,内存效率更高。列表在创建时即分配全部内存。
