一、什么是 range()?
range() 是 Python 的内置函数,用于生成一个不可变的数字序列。它通常用在 for 循环中,控制循环次数或生成索引序列。
for i inrange(5):print(i) # 输出 0 1 2 3 4
range() 返回的是一个 range 对象,而不是列表。它是一个惰性序列,只有在迭代时才会生成数字,因此非常节省内存。
二、range() 的三种调用方式
1. range(stop)
生成从 0 开始到 stop-1 的整数序列。
for i inrange(5):print(i, end=' ') # 0 1 2 3 4
2. range(start, stop)
生成从 start 开始到 stop-1 的整数序列。
for i inrange(2, 6):print(i, end=' ') # 2 3 4 5
3. range(start, stop, step)
生成从 start 开始,每次增加 step,直到接近 stop 的整数序列(不包含 stop)。
# 步长为正,递增for i inrange(1, 10, 2):print(i, end=' ') # 1 3 5 7 9# 步长为负,递减for i inrange(10, 0, -2):print(i, end=' ') # 10 8 6 4 2
三、参数详解
注意事项:
- •
step 不能为 0,否则会抛出 ValueError。 - • 如果
step > 0,start 必须小于 stop 才会生成非空序列。 - • 如果
step < 0,start 必须大于 stop 才会生成非空序列。
print(list(range(5, 2))) # [],因为 step 默认为 1,start>stop 无结果print(list(range(5, 2, -1))) # [5, 4, 3]
四、range 对象的特性
4.1 惰性求值
range() 返回的是一个可迭代对象,而不是列表。它不会一次性生成所有数字,而是在循环时逐个产生,因此无论范围多大,占用的内存都是固定的。
r = range(1000000) # 瞬间完成,内存占用很小print(r) # range(0, 1000000)
4.2 不可变序列
range 对象支持大多数序列操作,如索引、切片、长度判断等,但不能修改。
r = range(10)print(len(r)) # 10print(r[3]) # 3print(r[-1]) # 9print(r[2:5]) # range(2, 5) 切片返回新的 rangeprint(5in r) # True
4.3 与列表、元组的转换
可以将 range 对象转换为列表或元组,但注意这会占用内存。
numbers = list(range(5))print(numbers) # [0, 1, 2, 3, 4]t = tuple(range(3, 8))print(t) # (3, 4, 5, 6, 7)
五、常见用法与案例
5.1 固定次数的循环
# 循环 5 次for _ inrange(5):print("Hello")
5.2 遍历列表的索引
fruits = ["苹果", "香蕉", "橙子"]for i inrange(len(fruits)):print(f"{i}: {fruits[i]}")
5.3 倒序循环
for i inrange(10, 0, -1):print(i) # 10 9 8 ... 1
5.4 生成特定步长的数字
# 0 到 20 之间的偶数evens = list(range(0, 21, 2))print(evens) # [0, 2, 4, ..., 20]# 0 到 20 之间的奇数odds = list(range(1, 20, 2))print(odds) # [1, 3, 5, ..., 19]
5.5 累加求和
# 计算 1 到 100 的和total = 0for i inrange(1, 101): total += iprint(total) # 5050
5.6 嵌套循环中的使用
# 打印九九乘法表for i inrange(1, 10):for j inrange(1, i+1):print(f"{j}×{i}={i*j}", end="\t")print()
5.7 判断奇偶
# 输出 1-10 中的奇数和偶数for i inrange(1, 11):if i % 2 == 0:print(f"{i} 是偶数")else:print(f"{i} 是奇数")
六、性能优势
相比于使用列表(如 [0,1,2,3,4]),range 对象具有巨大的内存优势。假设我们需要一个包含 1 亿个数字的序列:
# 列表会占用巨大内存big_list = list(range(100000000)) # 可能耗尽内存# range 对象几乎不占内存big_range = range(100000000) # 瞬间完成
因此,在只需要迭代的情况下,应优先使用 range 而不是列表。
七、Python 2 与 Python 3 的区别
- • Python 2:
range() 返回的是一个列表,xrange() 返回的是类似 range 对象的可迭代序列。 - • Python 3:
range() 取代了 xrange(),返回的是 range 对象,不再有 xrange()。
如果你在 Python 2 中编写代码,注意内存问题,可能需要用 xrange() 代替 range()。但在 Python 3 中,直接使用 range() 即可。
八、常见错误与注意事项
8.1 忘记 stop 不包含自身
# 想生成 1 到 10,错误写法for i inrange(1, 10):print(i) # 只到 9# 正确写法for i inrange(1, 11):print(i)
8.2 step 为 0
range(1, 10, 0) # ValueError: range() arg 3 must not be zero
8.3 使用非整数参数
range(1.5, 5) # TypeError: 'float' object cannot be interpreted as an integer
8.4 负步长时 start 和 stop 的顺序
如果 step 为负数,要确保 start 大于 stop 才能生成序列。
# 想要倒序 5 到 1print(list(range(5, 0, -1))) # [5, 4, 3, 2, 1]print(list(range(0, 5, -1))) # [] 错误
8.5 误以为 range 返回列表
r = range(5)print(r) # range(0, 5),不是 [0,1,2,3,4]# 如果需要列表,显式转换print(list(r)) # [0, 1, 2, 3, 4]
九、综合练习
练习1:输出 20 以内的 3 的倍数
for i inrange(3, 21, 3):print(i, end=' ')
练习2:倒序输出列表元素
fruits = ["苹果", "香蕉", "橙子", "葡萄"]for i inrange(len(fruits)-1, -1, -1):print(fruits[i])
练习3:生成一个平方数列表
squares = [i**2for i inrange(1, 11)]print(squares)
练习4:模拟时钟秒针(0-59 循环)
for second inrange(60):print(f"第 {second} 秒")# 实际应用中可以用 time.sleep(1) 暂停一秒
十、总结
- •
range() 生成一个不可变的数字序列,常用于 for 循环。 - • 三种形式:
range(stop)、range(start, stop)、range(start, stop, step)。 - • 可以通过
list() 或 tuple() 转换为具体序列。 - • 与 Python 2 的
xrange() 对应,Python 3 的 range() 就是增强版。
掌握 range() 是高效编写循环的基础,尤其是需要控制次数、步长或反向遍历时,它是最佳选择。