• 五分钟搞懂python生成器迭代器


    生成器和迭代器都是Python语言中的重要概念。由于这两个概念比较抽象,但看文字比较难理解,所以本次我将概念和案例结合在一起,这样能够更好得搞懂这些知识点。

    1.迭代器

    迭代器是一种对象,它提供了一种遍历集合中元素的方式。它的作用是按照特定的顺序逐个访问集合中的元素,而不需要事先知道集合的长度或者将整个集合加载到内存中。

    在python总可通过调用 next() 方法来获取下一个元素。使用迭代器可以简化代码,提高效率,并且适用于处理大规模数据集合。

    案例:
    假设我们有一个非常大的列表,如果一次性将整个列表加载到内存中可能导致内存溢出,而使用迭代器可以避免这种情况:

    # 生成一个非常大的列表,例如1到1000000
    big_list = range(1, 1000001)
    
    # 使用迭代器逐个处理列表元素,而不是一次性加载整个列表到内存
    iter_obj = iter(big_list)
    
    # 计算列表中所有元素的总和
    total_sum = 0
    try:
        while True:
            element = next(iter_obj)
            total_sum += element
    except StopIteration:
        pass
    
    # 输出总和
    print("Total sum:", total_sum)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这个案例中,我们生成了一个非常大的列表big_list,然后使用迭代器iter_obj逐个处理列表元素,计算所有元素的总和。由于我们只在需要时逐个获取元素,而不是一次性加载整个列表到内存中,因此可以有效地节省内存空间,避免内存溢出问题

    2. 生成器

    生成器是一种特殊的迭代器,按需生成值,而不是一次性产生所有值,节省内存并支持惰性计算。

    下面是一个使用生成器的简单示例,该生成器返回斐波那契数列中的每个数字:

    def fibonacci_generator():
        a, b = 0, 1
        while True:
            yield a
            a, b = b, a + b
    
    fib = fibonacci_generator()
    
    # 打印前 10 个斐波那契数
    for i in range(10):
        print(next(fib))
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    通过循环迭代该生成器,我们可以打印出前 10 个斐波那契数。由于生成器是按需计算的,它不会一次性生成整个斐波那契数列,而是根据需要逐个生成。这种方式节省了内存,并且能够支持无限序列

    每次调用生成器对象的 next() 方法时,生成器函数会从上一次 yield 语句的位置开始执行,直到遇到下一个 yield 语句为止。这意味着生成器是按需生成值的,只有在需要时才会生成值。

    3、生产案例

    这里我们通过一个面试题带大家去深入理解

    服务器4G 内存怎么读取一个 5G 的数据?

    答:通过生成器,分多次读取,每次读取数量相对少的数据(比如 500MB)进行处理,处理结束后
    在读取后面的 500MB 的数据。

    # 定义一个生成器函数,在python中只要函数中使用yield字段就是一个生成器函数。生成器函数 用于创建 生成器迭代器 (generator iterator)。
    def process_data(file_path, batch_size):
        with open(file_path, 'rb') as file:
            while True:
                data = file.read(batch_size)
                if not data:
                    break
                # 在此处进行对数据的处理
                # 可以将处理后的结果返回,或者做其他操作
                yield data
    
    # 使用示例
    file_path = 'your_file_path'  # 文件路径
    batch_size = 500 * 1024 * 1024  # 500MB,注意单位为字节
    
    data_generator = process_data(file_path, batch_size)
    
    #迭代方法一
    while True:
        try:
            batch = next(data_generator)
            # 对每个批次的数据进行处理
        	# 可以调用相应的函数或方法进行处理
        	print(f"Processing {len(batch)} bytes of data")
        	# 这里只是简单示例,实际处理需要根据具体需求进行编写
        except StopIteration:
            break
    
    #迭代方法二
    #for batch in data_generator:
    #	print(f"Processing {len(batch)} bytes of data")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    Android-短信验证码
    从零学算法289
    Windows 安装 RabbitMq
    premiere 图片突出滑块效果
    设计模式-UML类图
    Axure RP 9 for Mac(原型设计软件)中文正式版
    算法通关村第14关【白银】| 堆的经典问题
    小黑子—spring:第二章 注解开发
    ucos任务调度原理
    基于Java实现的MD5算法实现
  • 原文地址:https://blog.csdn.net/litaimin/article/details/133019496