Python中for循环及其相关函数range(), zip(), enumerate()等
一、Python中的for循环及其相关函数
Python的for循环是算法竞赛中最常用的迭代工具之一,因其简洁和灵活性非常适合快速实现逻辑。以下详细讲解for循环及相关函数在竞赛中的使用场景。
1. for循环基本语法
Python的for循环用于遍历可迭代对象(如列表、字符串、元组等)。基本语法如下:
for 变量 in 可迭代对象:
# 循环体
竞赛中的典型用途:
- 遍历数组/列表:处理数组元素,如求和、查找、统计等。
- 遍历字符串:处理字符统计、模式匹配等问题。
- 结合其他函数(如range())实现固定次数的循环。
示例:计算数组的和
nums = [1, 2, 3, 4, 5]
total = 0
for num in nums:
total += num
print(total) # 输出15
2. range() 函数
range()
是for循环的常用搭档,用于生成一个整数序列,特别适合控制循环次数或生成索引。
语法:
range(start, stop, step) # 从start到stop-1,步长为step
start
:起始值(默认0,可省略)。stop
:结束值(不包含)。step
:步长(默认1,可省略)。
竞赛中的典型用途:
- 生成索引:遍历数组或矩阵的索引。
- 固定次数循环:执行特定次数的操作。
- 步长控制:处理等差数列或跳跃访问。
示例1:遍历数组索引
nums = [10, 20, 30, 40]
for i in range(len(nums)):
print(f"索引 {i} 的值是 {nums[i]}")
示例2:生成等差数列求和
total = 0
for i in range(1, 101, 2): # 1, 3, 5, ..., 99
total += i
print(total) # 输出奇数和
竞赛技巧:
range(n)
常用于0到n-1的索引循环。- 倒序遍历:
range(n-1, -1, -1)
。 - 注意
range()
返回的是一个range对象,内存效率高,适合大数据量。
3. enumerate() 函数
enumerate()
用于同时获取可迭代对象的索引和值,特别适合需要索引和元素一起操作的场景。
语法:
for index, value in enumerate(可迭代对象, start=0):
# 循环体
start
:索引的起始值(默认0)。
竞赛中的典型用途:
- 记录位置:在遍历数组时需要知道每个元素的索引。
- 修改数组:根据索引直接操作数组元素。
- 统计问题:记录特定元素出现的位置。
示例:找到数组中所有值为0的索引
nums = [1, 0, 3, 0, 5]
zeros = []
for i, num in enumerate(nums):
if num == 0:
zeros.append(i)
print(zeros) # 输出 [1, 3]
竞赛技巧:
- 替代
range(len())
的更优雅写法,代码更简洁。 - 可自定义起始索引,如
enumerate(lst, start=1)
,适合1-based索引的题目。
4. zip() 函数
zip()
用于将多个可迭代对象“并行”遍历,元素按位置配对组成元组。
语法:
for 变量1, 变量2, ... in zip(可迭代对象1, 可迭代对象2, ...):
# 循环体
竞赛中的典型用途:
- 多数组同步遍历:同时处理多个数组的对应元素。
- 矩阵操作:处理行列对应的数据。
- 键值对处理:将两个列表配对成类似字典的结构。
示例1:比较两个数组的对应元素
a = [1, 2, 3]
b = [4, 5, 6]
for x, y in zip(a, b):
print(x + y) # 输出5, 7, 9
示例2:转置矩阵
matrix = [[1, 2, 3], [4, 5, 6]]
transposed = list(zip(*matrix)) # [(1, 4), (2, 5), (3, 6)]
print(transposed)
竞赛技巧:
zip()
按最短的可迭代对象长度停止,适合长度不等的数组。- 使用
*
解包(如zip(*matrix)
)可实现矩阵转置或多维处理。 - 在Python 3中,
zip()
返回迭代器,需用list()
转换为列表。
5. 其他相关技巧
- 列表推导式:for循环的简洁写法,常用于快速生成列表。
竞赛中可简化代码,但注意可读性。squares = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25]
- 嵌套循环:处理矩阵或组合问题。
for i in range(n): for j in range(m): # 处理matrix[i][j]
- break和continue:
break
:跳出循环,常用于搜索到目标后提前结束。continue
:跳过当前迭代,常用于过滤无效数据。
竞赛注意事项:
- Python的for循环性能较C++慢,尽量避免不必要的循环。
- 输入处理:竞赛中常用
input()
读取数据,结合split()
和map()
处理多值输入。n = int(input()) nums = list(map(int, input().split()))
二、C++中的for循环
C++的for循环更底层,灵活性高,性能优于Python,特别适合算法竞赛中对时间复杂度要求严格的场景。以下详细讲解C++ for循环及其在竞赛中的用法。
1. for循环基本语法
C++的for循环有明确的初始化、条件和更新三个部分,适合精确控制循环。
语法:
for (初始化; 条件; 更新) {
// 循环体
}
- 初始化:定义循环变量(如
int i = 0
)。 - 条件:循环继续的条件(如
i < n
)。 - 更新:每次循环后变量的变化(如
i++
)。
竞赛中的典型用途:
- 遍历数组/向量:处理元素或索引。
- 固定次数循环:执行特定操作。
- 复杂迭代:自定义步长或多变量控制。
示例:计算数组的和
#include <vector>
#include <iostream>
using namespace std;
vector<int> nums = {1, 2, 3, 4, 5};
int total = 0;
for (int i = 0; i < nums.size(); i++) {
total += nums[i];
}
cout << total << endl; // 输出15
2. 范围for循环(C++11及以上)
C++11引入了基于范围的for循环,类似Python的for循环,适合直接遍历容器。
语法:
for (类型 变量 : 容器) {
// 循环体
}
竞赛中的典型用途:
- 快速遍历数组、向量或字符串。
- 简化代码,避免手动索引。
示例:遍历向量
vector<int> nums = {1, 2, 3, 4, 5};
for (int num : nums) {
cout << num << " ";
} // 输出1 2 3 4 5
注意:
- 如果需要修改元素,需用引用:
for (int& num : nums)
。 - 性能与传统for循环相当,但更简洁。
3. 竞赛中的常见模式
- 索引遍历:
常用于数组操作或需要索引的场景。for (int i = 0; i < n; i++) { // 处理arr[i] }
- 倒序遍历:
适合从后向前处理,如某些DP问题。for (int i = n - 1; i >= 0; i--) { // 处理arr[i] }
- 步长控制:
用于等差数列或跳跃访问。for (int i = 1; i <= 100; i += 2) { // 处理奇数 }
- 多变量循环:
适合双指针或对称处理。for (int i = 0, j = n - 1; i < j; i++, j--) { // 处理arr[i]和arr[j] }
4. 模拟Python的range/enumerate/zip
C++没有直接的range()
、enumerate()
或zip()
,但可以通过循环或其他方式模拟:
- 模拟range():直接用for循环。
for (int i = start; i < stop; i += step) { // 循环体 }
- 模拟enumerate():用索引和元素一起遍历。
vector<int> nums = {10, 20, 30}; for (int i = 0; i < nums.size(); i++) { cout << "索引 " << i << " 值 " << nums[i] << endl; }
- 模拟zip():并行遍历多个容器。
vector<int> a = {1, 2, 3}; vector<int> b = {4, 5, 6}; for (int i = 0; i < min(a.size(), b.size()); i++) { cout << a[i] + b[i] << endl; // 输出5, 7, 9 }
5. 竞赛中的高级用法
- 嵌套循环:处理矩阵或组合问题。
for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { // 处理matrix[i][j] } }
- 提前终止:
break
:跳出循环,适合搜索到目标后退出。continue
:跳过当前迭代,适合过滤无效数据。
- 性能优化:
- 使用
++i
而非i++
,微小性能提升。 - 避免不必要的容器拷贝,优先用引用。
- 对于大数组,尽量减少循环内计算(如提前计算
nums.size()
)。
- 使用
竞赛输入输出:
C++竞赛中常用cin
和cout
,需注意同步关闭以加速:
ios::sync_with_stdio(false);
cin.tie(nullptr);
示例:读取数组并求和
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int total = 0;
for (int num : nums) {
total += num;
}
cout << total << endl;
return 0;
}
6. C++ vs Python的对比
- 性能:C++ for循环更快,适合时间复杂度严格的题目。
- 语法:Python更简洁,C++更灵活但代码量稍多。
- 输入输出:C++需手动优化(如关闭同步),Python输入更简便。
- 库支持:Python内置函数(如zip())更丰富,C++需手动实现或用STL。