Hide Tia Switch Save

iterator用法

什么是 Iterator(迭代器)?

核心思想: 迭代器是一种设计模式,它提供了一种方法,能够顺序访问一个聚合对象(如列表、容器)中的各个元素,而又不需要暴露该对象的内部表示

你可以把迭代器想象成一个智能指针,它知道如何在容器中“遍历”或“移动”,并访问每个元素。

关键点:

  1. 抽象了遍历过程:无论底层数据结构是数组、链表、树还是哈希表,使用迭代器的代码看起来都差不多。
  2. 统一了访问接口:为不同的容器提供了一个统一的遍历访问接口。
  3. 保护了数据:用户通过迭代器访问元素,而不需要知道容器是如何存储这些元素的。

C++ 中的迭代器

在 C++ 中,迭代器是 STL(标准模板库)的核心组成部分之一。它被设计得像指针一样,支持 *(解引用)、++(自增)等操作。

C++ 迭代器的类别:

  • 输入迭代器:只读,且只能向前移动。
  • 输出迭代器:只写,且只能向前移动。
  • 前向迭代器:可读写,只能向前移动。
  • 双向迭代器:可读写,能向前和向后移动(如 list, map, set 的迭代器)。
  • 随机访问迭代器:功能最强,可读写,能跳跃式移动(如 vector, deque 的迭代器),支持 +, -, [] 等操作。

C++ 示例:

cpp
#include <iostream>
#include <vector>
#include <list>

int main() {
    // 1. 使用 vector (随机访问迭代器)
    std::vector<int> vec = {1, 2, 3, 4, 5};

    std::cout << "Vector iteration: ";
    // 使用 begin() 和 end() 获取迭代器
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " "; // 通过 * 解引用访问元素
    }
    std::cout << std::endl;

    // 2. 使用 list (双向迭代器)
    std::list<std::string> lst = {"Hello", "World", "C++"};

    std::cout << "List iteration: ";
    // 使用 auto 简化迭代器类型声明
    for (auto it = lst.begin(); it != lst.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 3. 反向迭代
    std::cout << "Reverse iteration: ";
    for (auto it = vec.rbegin(); it != vec.rend(); ++it) { // rbegin(), rend() 返回反向迭代器
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 4. 基于范围的 for 循环 (底层也是使用迭代器)
    std::cout << "Range-based for loop: ";
    for (const auto& value : vec) {
        std::cout << value << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Vector iteration: 1 2 3 4 5 
List iteration: Hello World C++ 
Reverse iteration: 5 4 3 2 1 
Range-based for loop: 1 2 3 4 5

Python 中的迭代器

Python 的迭代器协议更加简洁和统一,是 Python for 循环的基础。

Python 迭代器协议: 一个对象是迭代器,当且仅当它实现了以下两个方法:

  1. __iter__(): 返回迭代器对象本身(self)。
  2. __next__(): 返回容器的下一个元素。如果没有更多元素,则抛出 StopIteration 异常。

任何实现了 __iter__() 方法的对象都是 可迭代对象(Iterable)。当调用 iter() 函数时,它会调用对象的 __iter__() 方法来获取一个迭代器。

Python 示例:

python
# 1. 使用内置可迭代对象 (list, tuple, string, dict)
my_list = [1, 2, 3, 4, 5]

print("List iteration: ", end="")
# for 循环的底层机制:
#   1. 调用 iter(my_list) 获取一个迭代器
#   2. 重复调用 next(iterator) 获取值
#   3. 捕获 StopIteration 异常,结束循环
for item in my_list:
    print(item, end=" ")
print()

# 2. 手动模拟 for 循环的过程
print("Manual iteration: ", end="")
iterator_obj = iter(my_list) # 获取迭代器,相当于 my_list.__iter__()
while True:
    try:
        item = next(iterator_obj) # 获取下一个元素,相当于 iterator_obj.__next__()
        print(item, end=" ")
    except StopIteration:
        break
print()

# 3. 字典迭代
my_dict = {'a': 1, 'b': 2, 'c': 3}
print("Dict iteration (keys): ", end="")
for key in my_dict: # 默认迭代键
    print(key, end=" ")
print()

print("Dict iteration (items): ", end="")
for key, value in my_dict.items():
    print(f"{key}:{value}", end=" ")
print()

# 4. 创建一个自定义迭代器
class CountDown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        # 返回迭代器对象本身,因为它自己就是迭代器
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        else:
            num = self.current
            self.current -= 1
            return num

print("Custom iterator: ", end="")
counter = CountDown(3)
for num in counter:
    print(num, end=" ")
# 输出: 3 2 1

输出:

List iteration: 1 2 3 4 5 
Manual iteration: 1 2 3 4 5 
Dict iteration (keys): a b c 
Dict iteration (items): a:1 b:2 c:3 
Custom iterator: 3 2 1

C++ 与 Python 迭代器的对比总结

特性C++Python
核心概念类似智能指针,是 STL 算法的基石。遵循迭代器协议(__iter__, __next__),是 for 循环的基础。
获取方式通过容器的 begin(), end() 等方法。通过内置函数 iter() 作用于可迭代对象。
遍历方式使用 ++it 移动,*it 解引用。使用 next() 函数或 __next__() 方法。
结束判断将迭代器与 end() 返回的尾后迭代器比较。捕获 StopIteration 异常。
类别分为多种(输入、输出、前向、双向、随机访问),功能不同。协议统一,但行为可能不同(如序列是顺序,字典是键的顺序)。
语法糖基于范围的 for 循环 (for (auto x : container))。for 循环 (for x in iterable:)。

总结

  • Iterator 是一个强大的抽象工具,它让你可以用相同或相似的代码来处理各种不同的数据结构。
  • 在 C++ 中,迭代器是 STL 六大组件之一,与算法和容器紧密配合,是编写通用、高效 C++ 代码的关键。
  • 在 Python 中,迭代器协议是语言的核心特性之一,它使得 for 循环如此简洁和强大,并且可以轻松创建自定义的可迭代对象。

理解迭代器对于深入掌握这两种语言的编程范式至关重要。

C++与Python的tuple对比
github push commands