Python迭代器模式介绍、使用

一、Python迭代器模式介绍

Python迭代器模式是一种设计模式,它提供了一种访问容器对象中各个元素的统一接口,而不必暴露容器内部的细节。

在Python中,迭代器是指实现了__next__()方法的对象,这个方法返回容器中下一个元素,并在容器末尾时抛出StopIteration异常。通过使用迭代器模式,我们可以很方便地遍历序列、聚合和其他可迭代对象。

优点:

  1. 简化了遍历过程,无需关注底层实现;
  2. 降低了数据结构与遍历算法之间的耦合性;
  3. 支持延迟加载,节省内存资源。

缺点:

  1. 迭代器只能遍历容器中的数据,不能修改数据;
  2. 迭代器只能单向遍历,不能反向遍历。

应用场景: 在需要遍历序列或聚合(如列表、元组、字典等)的时候,可以使用迭代器模式。

使用方式: Python中内置的iter()函数返回一个迭代器对象,它接受一个可迭代对象作为参数,实现了__iter__()方法。调用迭代器的__next__()方法可以遍历容器对象的所有元素。

在应用程序开发中的使用: 迭代器模式可以用于处理大量数据的内存优化,实现了数据的按需加载。在Python中,生成器函数就是使用迭代器模式的常见例子。

二、迭代器模式使用

工作原理:

迭代器模式的核心思想是将容器对象与遍历算法分离开来,使它们可以独立地变化。容器对象实现了__iter__()方法,返回一个迭代器对象,迭代器对象实现了__next__()方法,用于遍历容器中的元素。通过这种方式,我们可以使用不同的遍历算法来遍历同一个容器对象,而不必对容器进行修改。

示例一:实现计算不及格学生数量功能

下面以一个简单的例子来说明Python迭代器模式的工作原理和使用方法。

假设我们有一个学生列表,需要计算其中不及格的学生人数。我们可以使用迭代器模式来实现:

定义了一个Student类,它有一个名字和一个成绩属性。我们还定义了一个StudentList类,它可以添加学生对象并返回一个迭代器对象。迭代器对象是StudentIterator类的实例,它实现了__next__()方法,可以遍历学生列表中的所有学生。

最后,我们定义了一个FailingStudentsCounter类,它使用StudentList对象来计算不及格学生的人数。我们通过调用StudentList对象的get_iterator()方法来获取迭代器对象,并使用while循环和try-except语句来遍历所有学生。当迭代器到达列表的末尾时,会抛出StopIteration异常,表示迭代结束。

# 定义类。 定义学生属性:名字、成绩
class Student():
    def __init__(self, name, score):
        self.name = name
        self.score = score

# 定义列表。定义学生列表
class StudentList():
    def __init__(self):
        self.students = []

    def add_student(self, student):
        self.students.append(student)

    def get_interator(self): # 获取迭代器
        return StudentIterator(self.students)

# 定义迭代器。
class StudentIterator():
    def __init__(self, students):
        self.students = students
        self.index = 0

    def __next__(self):
        if self.index >= len(self.students):
            raise StopIteration
        student = self.students[self.index]
        self.index += 1
        return student

# 定义成绩不及格学生类
class FailingStudentCounter():
    def count_failing_students(self, student_list):
        count = 0
        iterator = student_list.get_interator()
        while True:
            try:
                student = next(iterator)
                if student.score < 60:
                    count += 1
            except StopIteration:
                break
        return count

# 创建实例
stu1 = Student("name1", 80)
stu2 = Student("name2",55)
stu3 = Student("name3", 100)

student_list = StudentList()
student_list.add_student(stu1)
student_list.add_student(stu2)
student_list.add_student(stu3)

counter = FailingStudentCounter()
count = counter.count_failing_students(student_list)

print(count)

运行结果:

1

最终输出结果为"Number of failing students: 1",表示有一个不及格的学生。我们可以看到,迭代器模式可以简化遍历过程,降低数据结构与遍历算法之间的耦合性,从而提高代码的可读性和可重用性。

示例二:实现遍历列表功能

下面是一个简单的例子,展示了如何使用迭代器模式实现遍历一个列表的功能:

class MyInterator():
    def __init__(self, lst):
        self.lst = lst
        self.current = 0

    def __iter__(self): # 返回迭代器对象本身
        print("返回迭代器对象本身")
        return self

    def __next__(self): # 定义遍历逻辑
        print("遍历数据")
        if self.current == len(self.lst):
            print(f"当前第 {self.current} 个数据,停止遍历")
            raise StopIteration
        else:
            result = self.lst[self.current]
            self.current += 1
            return result

# 创建实例

my_lst = [11,3,5,0,9,2]
my_inter = MyInterator(my_lst)
for i in my_inter:
    print(i)

# 相当于:
for i in my_lst:
    print(i)

运行结果:

返回迭代器对象本身
遍历数据
11
遍历数据
3
遍历数据
5
遍历数据
0
遍历数据
9
遍历数据
2
遍历数据
当前第 6 个数据,停止遍历
11
3
5
0
9
2

在这个例子中,我们首先定义了一个MyIterator类,它实现了__iter__()和__next__()方法。iter()方法返回了迭代器对象自身,这样我们就可以使用for循环等工具对其进行遍历。而__next__()方法则定义了MyIterator类的遍历逻辑,检查当前位置是否越界,如果未越界则返回当前位置的元素,并将迭代器指针向前移动。

然后,我们使用my_lst列表来初始化MyIterator对象my_iter,并使用for循环遍历它。遍历过程中,Python会自动调用my_iter对象的__next__()方法来获取下一个元素,直到遍历结束。

需要注意的是,在Python中,列表本身就是一个可迭代对象,我们可以直接使用for循环遍历一个列表。

因此在实际开发中,我们可以根据需要选择使用列表自身的迭代方式,还是自定义一个迭代器类来实现遍历功能。

示例三:实现遍历字典功能

下面是一个简单的例子,展示了如何使用迭代器模式实现遍历一个字典的键和值的功能:

class MyInterator():
    def __init__(self, dic):
        self.current = 0
        self.keys = list(dic.keys())
        self.values = list(dic.values())

    def __iter__(self): # 返回迭代器对象本身
        print("返回迭代器对象本身")
        return self

    def __next__(self): # 定义遍历逻辑
        if self.current == len(self.keys):
            print(f"当前第 {self.current} 个数据,停止遍历")
            raise StopIteration
        else:
            key_result = self.keys[self.current]
            value_result = self.values[self.current]
            self.current += 1
            return key_result, value_result

# 创建实例

my_dct = {"a":1, "b":2, "c":3}
my_iter = MyInterator(my_dct)
for key,value in my_iter:
    print(key, value)


# 相当于:
for key in my_dct:
    print(key, my_dct[key])

运行结果:

返回迭代器对象本身
a 1
b 2
c 3
当前第 3 个数据,停止遍历
a 1
b 2
c 3

在这个例子中,我们同样定义了一个MyIterator类,它的构造函数中初始化了键和值的列表,并且在__next__()方法中同时返回了键和值。在遍历过程中,我们使用for循环遍历MyIterator对象,并将返回的键和值分别存储到key和value中输出。

因此,我们可以使用迭代器模式来实现遍历字典的功能,以便更加灵活地处理字典中的键和值。需要注意的是,在Python 3中,字典本身已经可以通过items()方法返回键值对元组的迭代器对象,因此我们也可以直接使用for循环遍历一个字典。

因此在实际开发中,我们可以根据需要选择使用字典自身的迭代方式,还是自定义一个迭代器类来实现遍历功能。

猜你喜欢

转载自blog.csdn.net/songpeiying/article/details/131979414