Python基础:range()函数的参数详解与高效用法
2026/7/12 19:14:00 网站建设 项目流程

Python基础:range()函数的参数详解与高效用法

一、开篇:for循环的灵魂伴侣

在Python中,range()函数几乎和for循环形影不离。每当你需要"重复N次"或"遍历一段数字"时,就会用到它:

foriinrange(10):print(i)# 0到9foriinrange(5,10):print(i)# 5到9foriinrange(0,10,2):print(i)# 0, 2, 4, 6, 8

看起来简单,但range()有一些不太广为人知的细节:它是惰性计算的、它支持负数步长、它可以用in做O(1)的成员检查、它甚至可以和len()配合使用。

⌨️ 更重要的,很多Python初学者滥用range(len(...)),而错过了更Pythonic的迭代方式。今天就来彻底掌握range()。

💡 全文将围绕三个核心问题展开:range()的参数到底怎么用、它为什么高效、什么时候该用什么时候不该用。

二、range()的三种参数形式

2.1 单参数:range(stop)

# range(stop) —— 从0到stop-1# 等价于数学中的 [0, stop)foriinrange(5):print(i,end=' ')# 输出: 0 1 2 3 4# 转换为列表查看内容print(list(range(5)))# [0, 1, 2, 3, 4]print(list(range(1)))# [0]print(list(range(0)))# [] —— stop=0 生成空range# print(list(range(-5))) # [] —— 负数也一样是空的# 📝 记忆技巧:range(n) 产生 n 个数字(从0到n-1)

2.2 双参数:range(start, stop)

# range(start, stop) —— 从start到stop-1# 等价于数学中的 [start, stop)foriinrange(5,10):print(i,end=' ')# 输出: 5 6 7 8 9print(list(range(3,8)))# [3, 4, 5, 6, 7]print(list(range(-3,3)))# [-3, -2, -1, 0, 1, 2]print(list(range(10,5)))# [] —— start > stop,空range# 计算range中的元素个数:stop - start(当start < stop时)print(len(range(5,10)))# 5print(len(range(-3,3)))# 6

2.3 三参数:range(start, stop, step)

# range(start, stop, step) —— 从start开始,每次加step,直到达到或超过stop# 正步长print(list(range(0,10,2)))# [0, 2, 4, 6, 8] —— 偶数print(list(range(1,10,2)))# [1, 3, 5, 7, 9] —— 奇数print(list(range(0,100,10)))# [0, 10, 20, 30, ..., 90]# 负步长(倒序)print(list(range(10,0,-1)))# [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]print(list(range(10,0,-2)))# [10, 8, 6, 4, 2]print(list(range(5,-5,-1)))# [5, 4, 3, 2, 1, 0, -1, -2, -3, -4]# ⚠️ step不能为0!# list(range(0, 10, 0)) # ValueError: range() arg 3 must not be zero# 步长的符号决定方向# step > 0: 从start向stop增长,要求 start < stop 才有元素# step < 0: 从start向stop减小,要求 start > stop 才有元素print(list(range(0,10,2)))# 有元素: start(0) < stop(10), step(2) > 0print(list(range(10,0,2)))# 空!start(10) > stop(0) 但 step(2) > 0print(list(range(10,0,-2)))# 有元素: start(10) > stop(0), step(-2) < 0

2.4 参数名称

# range的参数也可以使用关键字r1=range(stop=5)r2=range(start=2,stop=8)r3=range(start=10,stop=0,step=-2)# 但不常用的组合可能无法使用关键字# range(start=0, 10) # SyntaxError!位置参数不能在关键字参数后面# 📝 建议:大多数情况下使用位置参数更简洁# range(5) 而不是 range(stop=5)# range(2, 8) 而不是 range(start=2, stop=8)

三、range对象的高效特性

3.1 惰性计算(Lazy Evaluation)

# range() 不创建包含所有元素的列表# 它是一个"序列对象",按需生成值importsys# range对象非常小!r=range(1000000)# 一百万个元素lst=list(range(1000000))# 一百万个元素的列表print(f"range对象大小:{sys.getsizeof(r):,}bytes")# 约48 bytesprint(f"列表对象大小:{sys.getsizeof(lst):,}bytes")# 约8,000,000 bytes# range只在迭代时计算下一个值,不存储所有值# 这是它比列表高效得多的原因# range对象的重要特性r=range(10)print(len(r))# 10 —— O(1)计算print(r[0])# 0 —— 通过公式计算print(r[5])# 5print(r[-1])# 9 —— 支持负索引# print(r[100]) # IndexError

3.2 O(1)的成员检查

# range的 in 操作是O(1)的!# 它通过数学公式检查,而不是遍历所有元素r=range(0,1000000,2)print(500000inr)# True(O(1)时间!)print(500001inr)# False(O(1)时间!)# 对比列表的O(n)检查importtimeit lst=list(r)t_range=timeit.timeit(lambda:999998inr,number=10000)t_list=timeit.timeit(lambda:999998inlst,number=10000)print(f"range in:{t_range:.4f}s")# 极快print(f"list in:{t_list:.4f}s")# 慢得多# range的in检查原理defexplain_range_contains(r,x):"""解释range如何做成员检查"""start,stop,step=r.start,r.stop,r.stepifstep>0:in_range=start<=x<stopifin_range:# 检查x是否落在step的倍数上return(x-start)%step==0else:in_range=stop<x<=startifin_range:return(x-start)%step==0returnFalse

3.3 支持索引和切片

r=range(0,100,3)# 0, 3, 6, ..., 99# 索引——O(1)计算print(r[0])# 0print(r[1])# 3print(r[10])# 30print(r[-1])# 99 —— 最后一个# 切片——返回新的range对象(也是O(1)!)print(r[5:15])# range(15, 45, 3)print(r[:5])# range(0, 15, 3)print(r[::2])# range(0, 100, 6) —— 步长加倍# 验证切片结果print(list(r[5:15]))# [15, 18, 21, 24, 27, 30, 33, 36, 39, 42]print(list(r[:5]))# [0, 3, 6, 9, 12]print(list(r[::2]))# [0, 6, 12, 18, ...]# 支持 reversed()print(list(reversed(r))[:5])# [99, 96, 93, 90, 87]# 支持 == != 比较r1=range(0,10,2)r2=range(0,10,2)r3=range(0,9,2)print(r1==r2)# True —— 相同参数print(r1==r3)# False

四、range()的实用技巧

4.1 常用模式

# 模式1:重复N次for_inrange(10):print("Hello")# 打印10次# 模式2:生成N个元素的列表squares=[i**2foriinrange(1,11)]print(squares)# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# 模式3:倒序(两种方式)# 方式A:使用reversed()foriinreversed(range(10)):print(i,end=' ')# 9 8 7 6 5 4 3 2 1 0# 方式B:使用负步长foriinrange(9,-1,-1):print(i,end=' ')# 9 8 7 6 5 4 3 2 1 0# 模式4:跳过foriinrange(0,100,10):print(i,end=' ')# 0 10 20 30 40 50 60 70 80 90# 模式5:并行遍历多个列表(避免range(len()))names=["张三","李四","王五"]scores=[85,92,78]# ❌ 不推荐foriinrange(len(names)):print(f"{names[i]}:{scores[i]}")# ✅ 推荐forname,scoreinzip(names,scores):print(f"{name}:{score}")

4.2 range()的数学应用

# 生成等差数列defarithmetic_sequence(start,end,step):"""生成等差数列"""returnlist(range(start,end+(1ifstep>0else-1),step))print(arithmetic_sequence(1,10,2))# [1, 3, 5, 7, 9]print(arithmetic_sequence(10,1,-3))# [10, 7, 4, 1]# 生成乘法表foriinrange(1,10):forjinrange(1,i+1):print(f"{j}×{i}={i*j}",end='\t')print()# 斐波那契数列(利用range的迭代次数控制)deffibonacci(n):"""生成前n个斐波那契数"""result=[]a,b=0,1for_inrange(n):result.append(a)a,b=b,a+breturnresultprint(fibonacci(10))# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]# 分页数据生成defpaginate(items,page_size):"""将数据分页"""pages=[]foriinrange(0,len(items),page_size):pages.append(items[i:i+page_size])returnpages data=list(range(25))pages=paginate(data,10)fori,pageinenumerate(pages,1):print(f"第{i}页:{page}")

4.3 range()与列表索引的高级配合

# 当你确实需要索引时,range(len())是可以的# 但通常在特定的场景下# 场景1:修改原列表的元素numbers=[1,2,3,4,5]foriinrange(len(numbers)):numbers[i]=numbers[i]**2print(numbers)# [1, 4, 9, 16, 25]# 场景2:操作相邻元素data=[3,1,4,1,5,9,2,6]foriinrange(len(data)-1):ifdata[i]>data[i+1]:print(f"下降:{data[i]}{data[i+1]}at index{i}")# 场景3:从后往前处理stack=['a','b','c','d','e']foriinrange(len(stack)-1,-1,-1):print(f"弹出:{stack[i]}")# 场景4:跳跃处理data=list(range(20))# 每3个元素取一个foriinrange(0,len(data),3):print(data[i],end=' ')# 0 3 6 9 12 15 18

五、range() vs 其他迭代方式

5.1 选择合适的迭代方式

data=["apple","banana","orange","grape","kiwi"]# 1. 只需要值 → 直接迭代foritemindata:print(item)# 2. 需要索引和值 → enumerate()fori,iteminenumerate(data):print(f"{i}:{item}")# 3. 只需要索引 → range(len())foriinrange(len(data)):print(f"索引:{i}")# 4. 需要修改原列表 → range(len())foriinrange(len(data)):data[i]=data[i].upper()# 5. 需要跳步 → range() 配合步长或切片foriinrange(0,len(data),2):print(data[i])# 或者切片 + 直接迭代foritemindata[::2]:print(item)# 6. 需要反向 → reversed() 或 range(len()-1, -1, -1)foriteminreversed(data):print(item)# 7. 需要特定范围内的迭代 → range(start, stop)foriinrange(5,10):print(i)

5.2 range vs list 内存对比

importsys# range对象的优势在循环中体现# for i in range(10000000): # 只占用约48字节# pass# for i in list(range(10000000)): # 占用约80MB!不要这样做# pass# 对比不同大小的range和listsizes=[100,10000,1000000]forninsizes:r=range(n)l=list(r)print(f"n={n:>10,}: range={sys.getsizeof(r):>6}bytes, list={sys.getsizeof(l):>12,}bytes")

六、实战案例

6.1 进度条模拟器

importtimedefsimulate_progress(total,desc="处理中"):"""模拟进度条 —— range控制迭代"""bar_length=30foriinrange(total+1):percent=i/total filled=int(bar_length*percent)bar='█'*filled+'░'*(bar_length-filled)print(f'\r{desc}|{bar}|{percent:.0%}({i}/{total})',end='')time.sleep(0.05)print()# 换行# simulate_progress(50, "下载中")

6.2 批量任务处理器

classBatchProcessor:"""批量任务处理器 —— range控制批处理"""def__init__(self,items,batch_size=100):self.items=items self.batch_size=batch_size self.results=[]defprocess(self,worker_func):"""分批处理所有元素"""total=len(self.items)batches=(total+self.batch_size-1)//self.batch_sizeforbatch_idxinrange(batches):start=batch_idx*self.batch_size end=min(start+self.batch_size,total)batch=self.items[start:end]print(f"处理批次{batch_idx+1}/{batches}"f"(元素{start}-{end-1}, 共{len(batch)}个)")# 处理批次batch_results=[worker_func(item)foriteminbatch]self.results.extend(batch_results)# 模拟批次间暂停time.sleep(0.1)print(f"\n✅ 全部处理完成:{len(self.results)}个结果")returnself.results# 使用# processor = BatchProcessor(range(1000), batch_size=150)# results = processor.process(lambda x: x ** 2)

七、本章小结

✅ 本文我们全面掌握了range()函数:

  1. 三种参数形式range(stop)从0到stop-1;range(start, stop)从start到stop-1;range(start, stop, step)以step步长递增/递减。

  2. 高效特性:惰性计算(不存储所有元素)、O(1)成员检查、支持索引和切片、内存占用极低(约48字节)。

  3. 实用技巧:重复N次用for _ in range(n)、倒序用reversed(range(n))range(n-1, -1, -1)、跳步用步长参数。

  4. 何时用range(len()):修改原列表元素、操作相邻元素、跳跃遍历——这些场景下range(len())是合理的。但对于简单的遍历值,直接用for item in items更Pythonic。

range()是for循环的最佳搭档,理解它的每一个参数和特性,能让你写出更高效、更优雅的循环代码。⌨️ 下一篇文章,我们将学习enumerate()——让带索引的遍历更加优雅。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询