详细解析 Python 中超级重大的内置函数 range()。
range() 函数用于生成一个不可变的数字序列,一般用于循环中。
# 生成 0 到 4 的整数序列
r = range(5)
print(list(r)) # 输出: [0, 1, 2, 3, 4]
# 常用于 for 循环
for i in range(3):
print(i, end=' ')
# 输出: 0 1 2# 生成 5 到 9 的整数序列
r = range(5, 10)
print(list(r)) # 输出: [5, 6, 7, 8, 9]
# 负数的起始值
r = range(-3, 3)
print(list(r)) # 输出: [-3, -2, -1, 0, 1, 2]# 步长为 2
r = range(0, 10, 2)
print(list(r)) # 输出: [0, 2, 4, 6, 8]
# 负步长(递减)
r = range(10, 0, -2)
print(list(r)) # 输出: [10, 8, 6, 4, 2]
# 小数步长(不支持)
# r = range(0, 1, 0.1) # TypeError: 'float' object cannot be interpreted as an integer# range 对象超级节省内存
large_range = range(1000000)
print(f"range(1000000) 内存占用: {large_range.__sizeof__()} 字节") # 输出: 48 字节
# 对比列表
large_list = list(range(1000000))
print(f"列表内存占用: {large_list.__sizeof__()} 字节") # 输出: 8000056 字节# range 是惰性的,只在需要时生成值
r = range(10**9) # 立即创建,几乎不占内存
print(r) # 输出: range(0, 1000000000)
# 只有在转换为列表或迭代时才会真正生成值
first_three = list(r)[:3] # 只生成前3个值
print(first_three) # 输出: [0, 1, 2]# 基本的 for 循环
for i in range(5):
print(f"第 {i} 次循环")
# 指定起始值
for i in range(3, 8):
print(i, end=' ') # 输出: 3 4 5 6 7
# 带步长的循环
for i in range(0, 10, 3):
print(i, end=' ') # 输出: 0 3 6 9# 生成索引序列
fruits = ['apple', 'banana', 'cherry', 'date']
for i in range(len(fruits)):
print(f"索引 {i}: {fruits[i]}")
# 创建数字列表
numbers = list(range(10))
print(numbers) # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 生成特定范围的列表
even_numbers = list(range(0, 20, 2))
print(even_numbers) # 输出: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]# 计算累加和
total = sum(range(1, 101)) # 1到100的和
print(f"1到100的和: {total}") # 输出: 5050
# 生成等差数列
def arithmetic_sequence(start, diff, n):
"""生成等差数列"""
return list(range(start, start + diff * n, diff))
seq = arithmetic_sequence(2, 3, 5)
print(seq) # 输出: [2, 5, 8, 11, 14]
# 生成几何序列(需要配合其他方法)
def geometric_sequence(start, ratio, n):
"""生成几何序列"""
return [start * (ratio ** i) for i in range(n)]
geo_seq = geometric_sequence(2, 3, 5)
print(geo_seq) # 输出: [2, 6, 18, 54, 162]# 生成二维网格坐标
rows, cols = 3, 4
grid = []
for i in range(rows):
for j in range(cols):
grid.append((i, j))
print("网格坐标:", grid)
# 创建单位矩阵
def identity_matrix(n):
"""创建 n x n 单位矩阵"""
matrix = []
for i in range(n):
row = []
for j in range(n):
row.append(1 if i == j else 0)
matrix.append(row)
return matrix
id_matrix = identity_matrix(3)
print("单位矩阵:")
for row in id_matrix:
print(row)# 反向循环
for i in range(10, 0, -1):
print(i, end=' ') # 输出: 10 9 8 7 6 5 4 3 2 1
# 反向索引访问
fruits = ['apple', 'banana', 'cherry']
for i in range(len(fruits)-1, -1, -1):
print(fruits[i], end=' ') # 输出: cherry banana apple# 检查数字是否在范围内
def in_range(number, start, stop):
"""检查数字是否在范围内"""
return number in range(start, stop)
print(in_range(5, 0, 10)) # 输出: True
print(in_range(15, 0, 10)) # 输出: False
# 使用 range 进行切片式操作
def get_slice(sequence, start, stop, step=1):
"""模拟切片操作"""
indices = range(start, stop, step)
return [sequence[i] for i in indices if 0 <= i < len(sequence)]
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = get_slice(data, 2, 8, 2)
print(result) # 输出: [2, 4, 6]fruits = ['apple', 'banana', 'cherry']
# 使用 range (需要手动处理索引)
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
# 使用 enumerate (更Pythonic)
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 两种方式输出一样,但 enumerate 更简洁import timeit
# 性能比较:range vs 列表
def test_range_performance():
# range 方式
range_time = timeit.timeit('for i in range(10000): pass', number=1000)
# 列表方式
list_time = timeit.timeit('for i in list(range(10000)): pass', number=1000)
print(f"range 循环时间: {range_time:.6f}秒")
print(f"列表循环时间: {list_time:.6f}秒")
print(f"性能提升: {list_time/range_time:.1f}倍")
test_range_performance()# 无效的范围
empty_range = range(5, 3) # start > stop, step=1
print(list(empty_range)) # 输出: []
# 零步长
try:
zero_step = range(0, 10, 0) # ValueError: range() arg 3 must not be zero
except ValueError as e:
print(f"错误: {e}")
# 浮点数参数
try:
float_range = range(1.5, 5.5) # TypeError: 'float' object cannot be interpreted as an integer
except TypeError as e:
print(f"错误: {e}")
# 大数范围(可以处理)
big_range = range(10**18, 10**18 + 5)
print(big_range) # 输出: range(1000000000000000000, 1000000000000000005)
print(list(big_range)) # 输出: [1000000000000000000, 1000000000000000001, ...]# 与 zip() 配合
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
for i, (name, score) in enumerate(zip(names, scores)):
print(f"{i}: {name} - {score}")
# 与 map() 配合
squares = list(map(lambda x: x**2, range(10)))
print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 与 filter() 配合
even_squares = list(filter(lambda x: x % 2 == 0, map(lambda x: x**2, range(10))))
print(even_squares) # 输出: [0, 4, 16, 36, 64]class FloatRange:
"""支持浮点数的范围类"""
def __init__(self, start, stop=None, step=1.0):
if stop is None:
start, stop = 0.0, start
self.start = start
self.stop = stop
self.step = step
self.current = start
def __iter__(self):
return self
def __next__(self):
if (self.step > 0 and self.current >= self.stop) or
(self.step < 0 and self.current <= self.stop):
raise StopIteration
result = self.current
self.current += self.step
return result
# 使用自定义浮点范围
fr = FloatRange(0, 1, 0.1)
print(list(fr)) # 输出: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]# 好的实践
def process_large_data(n):
"""处理大数据的高效方式"""
# 保持 range 对象,避免内存占用
total = 0
for i in range(n):
total += i
return total
# 不好的实践
def process_large_data_bad(n):
"""低效的方式"""
# 生成整个列表,占用大量内存
numbers = list(range(n))
return sum(numbers)特性 | 描述 |
功能 | 生成不可变数字序列 |
语法 | range(stop) 或 range(start, stop[, step]) |
返回值 | range 对象(可迭代) |
内存效率 | 极高(固定大小) |
主要用途 | 循环控制、序列生成、数学计算 |
性能特点 | 惰性求值,高效内存使用 |
适用场景 | 循环、迭代、序列操作、算法实现 |
range() 是 Python 中极其重大和高效的内置函数,它提供了生成数字序列的优雅方式,特别适合处理大规模数据和在循环中使用。掌握 range() 的各种用法对于编写高效的 Python 代码至关重大。