详解Python 生成器

  • Post category:Python

Python 的生成器是一种特殊的迭代器,它可以基于 yield 语句动态生成一个序列,而不是在内存中创建完整的序列。这使得生成器在处理一些大型数据集时非常有用。在本文中,我们将提供一份完整攻略,讲解如何使用 Python 的生成器。

生成器自定义

生成器自定义十分简单,只需要使用 yield 语句即可。下面是一个简单的示例,它展示了如何创建一个简单的生成器:

def simple_generator():
    yield 1
    yield 2
    yield 3

请注意,函数使用 yield 语句来返回数据,并且可以多次调用该函数,以产生不同的结果。在此示例中,每次调用函数时,它将生成一个数字,然后暂停,以等待下一次迭代调用。

生成器表达式

生成器表达式是一种使用类似于列表推导式的语法来创建生成器的方法。可以使用 for 循环或其他类似的语法来生成序列。下面是一个简单的示例,展示了如何使用生成器表达式来创建一个生成器:

square_generator = (x**2 for x in range(1, 10))

在这个示例中,使用了一个 for 循环语句来生成 1 到 10 之间的数字。每个数字都通过 **2 运算符来平方,并最终产生一个生成器。这个生成器可以像任何其他生成器一样使用。

生成器函数

生成器函数是一种特殊的函数,它通过 yield 语句来产生一个序列。可以像任何其他函数一样定义生成器函数,并使用 yield 语句来产生序列中的下一个值。下面是一个简单的示例,展示了如何使用生成器函数来创建生成器:

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

在这个示例中,函数不是简单地返回一个值,而是使用 while 循环无限地生成下一个斐波那契数列中的值。每个斐波那契数列中的值都通过 yield 语句返回,并在下一次调用函数时继续执行。

示例

下面是一个复杂一些的示例,使用生成器来产生一份学生的成绩单。首先,我们定义一个学生类:

class Student:
    def __init__(self, name, grades):
        self.name = name
        self.grades = grades

    def __str__(self):
        return f"{self.name}: {self.grades}"

然后,我们使用生成器函数来生成学生的成绩单:

def grade_report(students):
    for student in students:
        average_grade = sum(student.grades) / len(student.grades)
        yield f"{student.name}: {average_grade:.2f}"

students = [Student('Alice', [80, 90, 95]), Student('Bob', [70, 85, 75]), Student('Charlie', [90, 91, 92])]
for report in grade_report(students):
    print(report)

在这个示例中,我们首先定义了一个学生类,它有一个 name 和 grades 属性。接下来,我们定义了一个生成器函数 grade_report,它使用 for 循环来遍历学生列表,并为每个学生计算平均成绩。在每次循环中,使用 yield 语句来产生一个成绩单。最后,我们使用 for 循环来遍历生成的成绩单,并打印每个成绩单的内容。

这个示例说明了如何使用生成器来处理实际问题,并展示了生成器的灵活性和强大的功能。