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

 更新时间:2026年07月14日 08:43:59   作者:星河耀银海  
本文将深入解析range()函数的三种参数形式、惰性计算和O(1)成员检查等高效特性,并教你何时用range(len()),何时直接迭代更Pythonic,掌握这些让你的循环代码既优雅又省内存

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

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

for i in range(10):
    print(i)          # 0到9

for i in range(5, 10):
    print(i)          # 5到9

for i in range(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)

for i in range(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)

for i in range(5, 10):
    print(i, end=' ')
# 输出: 5 6 7 8 9

print(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)))     # 5
print(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) > 0
print(list(range(10, 0, 2)))    # 空!start(10) > stop(0) 但 step(2) > 0
print(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() 不创建包含所有元素的列表
# 它是一个"序列对象",按需生成值

import sys

# range对象非常小!
r = range(1000000)          # 一百万个元素
lst = list(range(1000000))  # 一百万个元素的列表

print(f"range对象大小: {sys.getsizeof(r):,} bytes")      # 约48 bytes
print(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])            # 5
print(r[-1])           # 9 —— 支持负索引
# print(r[100])        # IndexError

3.2 O(1)的成员检查

# range的 in 操作是O(1)的!
# 它通过数学公式检查,而不是遍历所有元素

r = range(0, 1000000, 2)
print(500000 in r)     # True(O(1)时间!)
print(500001 in r)     # False(O(1)时间!)

# 对比列表的O(n)检查
import timeit
lst = list(r)
t_range = timeit.timeit(lambda: 999998 in r, number=10000)
t_list = timeit.timeit(lambda: 999998 in lst, number=10000)
print(f"range in: {t_range:.4f}s")   # 极快
print(f"list  in: {t_list:.4f}s")    # 慢得多

# range的in检查原理
def explain_range_contains(r, x):
    """解释range如何做成员检查"""
    start, stop, step = r.start, r.stop, r.step
    
    if step > 0:
        in_range = start <= x < stop
        if in_range:
            # 检查x是否落在step的倍数上
            return (x - start) % step == 0
    else:
        in_range = stop < x <= start
        if in_range:
            return (x - start) % step == 0
    return False

3.3 支持索引和切片

r = range(0, 100, 3)    # 0, 3, 6, ..., 99

# 索引——O(1)计算
print(r[0])    # 0
print(r[1])    # 3
print(r[10])   # 30
print(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 _ in range(10):
    print("Hello")     # 打印10次

# 模式2:生成N个元素的列表
squares = [i**2 for i in range(1, 11)]
print(squares)    # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# 模式3:倒序(两种方式)
# 方式A:使用reversed()
for i in reversed(range(10)):
    print(i, end=' ')   # 9 8 7 6 5 4 3 2 1 0

# 方式B:使用负步长
for i in range(9, -1, -1):
    print(i, end=' ')   # 9 8 7 6 5 4 3 2 1 0

# 模式4:跳过
for i in range(0, 100, 10):
    print(i, end=' ')   # 0 10 20 30 40 50 60 70 80 90

# 模式5:并行遍历多个列表(避免range(len()))
names = ["张三", "李四", "王五"]
scores = [85, 92, 78]

# ❌ 不推荐
for i in range(len(names)):
    print(f"{names[i]}: {scores[i]}")

# ✅ 推荐
for name, score in zip(names, scores):
    print(f"{name}: {score}")

4.2 range()的数学应用

# 生成等差数列
def arithmetic_sequence(start, end, step):
    """生成等差数列"""
    return list(range(start, end + (1 if step > 0 else -1), step))

print(arithmetic_sequence(1, 10, 2))    # [1, 3, 5, 7, 9]
print(arithmetic_sequence(10, 1, -3))   # [10, 7, 4, 1]

# 生成乘法表
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j}", end='\t')
    print()

# 斐波那契数列(利用range的迭代次数控制)
def fibonacci(n):
    """生成前n个斐波那契数"""
    result = []
    a, b = 0, 1
    for _ in range(n):
        result.append(a)
        a, b = b, a + b
    return result

print(fibonacci(10))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

# 分页数据生成
def paginate(items, page_size):
    """将数据分页"""
    pages = []
    for i in range(0, len(items), page_size):
        pages.append(items[i:i + page_size])
    return pages

data = list(range(25))
pages = paginate(data, 10)
for i, page in enumerate(pages, 1):
    print(f"第{i}页: {page}")

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

# 当你确实需要索引时,range(len())是可以的
# 但通常在特定的场景下

# 场景1:修改原列表的元素
numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers)):
    numbers[i] = numbers[i] ** 2
print(numbers)  # [1, 4, 9, 16, 25]

# 场景2:操作相邻元素
data = [3, 1, 4, 1, 5, 9, 2, 6]
for i in range(len(data) - 1):
    if data[i] > data[i + 1]:
        print(f"下降: {data[i]} → {data[i+1]} at index {i}")

# 场景3:从后往前处理
stack = ['a', 'b', 'c', 'd', 'e']
for i in range(len(stack) - 1, -1, -1):
    print(f"弹出: {stack[i]}")

# 场景4:跳跃处理
data = list(range(20))
# 每3个元素取一个
for i in range(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. 只需要值 → 直接迭代
for item in data:
    print(item)

# 2. 需要索引和值 → enumerate()
for i, item in enumerate(data):
    print(f"{i}: {item}")

# 3. 只需要索引 → range(len())
for i in range(len(data)):
    print(f"索引: {i}")

# 4. 需要修改原列表 → range(len())
for i in range(len(data)):
    data[i] = data[i].upper()

# 5. 需要跳步 → range() 配合步长或切片
for i in range(0, len(data), 2):
    print(data[i])

# 或者切片 + 直接迭代
for item in data[::2]:
    print(item)

# 6. 需要反向 → reversed() 或 range(len()-1, -1, -1)
for item in reversed(data):
    print(item)

# 7. 需要特定范围内的迭代 → range(start, stop)
for i in range(5, 10):
    print(i)

5.2 range vs list 内存对比

import sys

# range对象的优势在循环中体现
# for i in range(10000000):  # 只占用约48字节
#     pass

# for i in list(range(10000000)):  # 占用约80MB!不要这样做
#     pass

# 对比不同大小的range和list
sizes = [100, 10000, 1000000]
for n in sizes:
    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 进度条模拟器

import time

def simulate_progress(total, desc="处理中"):
    """模拟进度条 —— range控制迭代"""
    bar_length = 30
    
    for i in range(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 批量任务处理器

class BatchProcessor:
    """批量任务处理器 —— range控制批处理"""
    
    def __init__(self, items, batch_size=100):
        self.items = items
        self.batch_size = batch_size
        self.results = []
    
    def process(self, worker_func):
        """分批处理所有元素"""
        total = len(self.items)
        batches = (total + self.batch_size - 1) // self.batch_size
        
        for batch_idx in range(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) for item in batch]
            self.results.extend(batch_results)
            
            # 模拟批次间暂停
            time.sleep(0.1)
        
        print(f"\n✅ 全部处理完成: {len(self.results)} 个结果")
        return self.results

# 使用
# processor = BatchProcessor(range(1000), batch_size=150)
# results = processor.process(lambda x: x ** 2)

七、本章小结

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

  • 三种参数形式range(stop)从0到stop-1;range(start, stop)从start到stop-1;range(start, stop, step)以step步长递增/递减。
  • 高效特性:惰性计算(不存储所有元素)、O(1)成员检查、支持索引和切片、内存占用极低(约48字节)。
  • 实用技巧:重复N次用for _ in range(n)、倒序用reversed(range(n))range(n-1, -1, -1)、跳步用步长参数。
  • 何时用range(len()):修改原列表元素、操作相邻元素、跳跃遍历——这些场景下range(len())是合理的。但对于简单的遍历值,直接用for item in items更Pythonic。

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

到此这篇关于Python基础指南之range()函数的参数详解与高效用法的文章就介绍到这了,更多相关Python range()函数用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python简单实现秒表计时功能

    python简单实现秒表计时功能

    文章主要介绍了实现秒表功能的方法和可能遇到的问题,包括使用round()函数进行四舍五入、在PyCharm中模拟终端接收键盘输入以及print语句中的\r和end的应用
    2026-05-05
  • scrapy-redis源码分析之发送POST请求详解

    scrapy-redis源码分析之发送POST请求详解

    这篇文章主要给大家介绍了关于scrapy-redis源码分析之发送POST请求的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用scrapy-redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Python控制Firefox方法总结

    Python控制Firefox方法总结

    在本文里我们给大家分享了关于如何用Python控制Firefox的知识点总结,有此需要的朋友们可以参阅下。
    2019-06-06
  • Python全栈之列表数据类型详解

    Python全栈之列表数据类型详解

    这篇文章主要给大家介绍了关于Python全栈之列表数据类型的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • keras打印loss对权重的导数方式

    keras打印loss对权重的导数方式

    这篇文章主要介绍了keras打印loss对权重的导数方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • python使用Openpyxl操作Excel文件的实现

    python使用Openpyxl操作Excel文件的实现

    openpyxl 是一个用于在 Python 中读取和写入 Excel 文件的优秀库,本文主要介绍了python使用Openpyxl操作Excel文件的实现,具有一定的参考价值,感兴趣的可以了解一下
    2025-04-04
  • 详解win10下pytorch-gpu安装以及CUDA详细安装过程

    详解win10下pytorch-gpu安装以及CUDA详细安装过程

    这篇文章主要介绍了win10下pytorch-gpu安装以及CUDA详细安装过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • python如何绘制疫情图

    python如何绘制疫情图

    这篇文章主要介绍了python如何绘制疫情图,帮助大家理解和学习用python绘制图像,感兴趣的朋友可以了解下
    2020-09-09
  • Python常用内置模块日志、随机数、时间、OS与JSON详解

    Python常用内置模块日志、随机数、时间、OS与JSON详解

    本文介绍了Python开发中常用的五大模块:日志、随机数、时间、系统文件操作及JSON数据处理,详细讲解了各模块的的常见函数及其应用场景,需要的朋友可以参考下
    2026-05-05
  • Python中的缩进是什么意思

    Python中的缩进是什么意思

    在Python中,缩进是指在代码中使用空格或制表符来表示代码块的层次结构,Python使用缩进作为语法的一部分,以定义代码的逻辑结构和代码块的范围,本文介绍Python中的缩进是什么意思,感兴趣的朋友一起看看吧
    2024-01-01

最新评论