迭代器和生成器

迭代器和生成器

简单理解,可以一个个读取操作的对象,称为可迭代对象。可迭代对象就是你能用for循环迭代它的元素,迭代器是指可以用next()获取它的下一个值。生成器依赖于迭代器,在Python中,一边迭代(循环)一边计算的机制,称为生成器。生成器能够迭代的关键是因为它有一个__next__方法,因此生成器首先得是一个迭代器,每迭代一次,生成一个元素。

迭代器

Python 3.12.7 (main, Nov  8 2024, 17:55:36) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> l = ['a','b','c']
>>> for i in l:
...     print(i)
...
a
b
c
>>> i = iter(l)
>>> next(i)
'a'
>>> next(i)
'b'
>>> next(i)
'c'
>>> i = l.__iter__()
>>> i.__next__()
'a'
>>> i.__next__()
'b'
>>> i.__next__()
'c'
>>> i.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

自定义迭代器的代码

#!/usr/bin/env python

class Test:
    def __init__(self,a,b):
        self.a = a
        self.b = b
        
    def __iter__(self):
        return self
    
    def __next__(self):
        self.a += 1
        if self.a > self.b:
           raise StopIteration
        return self.a


test = Test(0,10)
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))

运行结果

┌──(root㉿kali)-[~/python_code/python_4]
└─# python iteration.py
1
2
3
4
5
6
7
8
9
10
Traceback (most recent call last):
  File "/root/python_code/python_4/iteration.py", line 29, in <module>
    print(next(test))
          ^^^^^^^^^^
  File "/root/python_code/python_4/iteration.py", line 14, in __next__
    raise StopIteration
StopIteration

生成器

Python 3.12.7 (main, Nov  8 2024, 17:55:36) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> g = (x**x for x in range(1,4))
>>> g
<generator object <genexpr> at 0x7f66f2e26cf0>
>>> for x in g:
...     print(x)
...
1
4
27
>>>

斐波那契数列

#!/usr/bin/env python

def fib(n):
    current = 0
    a,b = 1,1
    while current < n:
        yield a
        a,b = b,a+b
        current += 1

f5 = fib(5)

for i in f5:
    print(i)

运行结果

┌──(root㉿kali)-[~/python_code/python_4]
└─# python Fibonacci.py
1
1
2
3
5

详解迭代器和生成器(了解)

Python迭代器是Python中用于遍历数据集合的重要工具,它允许我们以高效、灵活的方式访问数据集合中的元素。以下是关于Python迭代器的详细解析。

1. 迭代器的基本概念

1.1 可迭代对象(Iterable)

  • 定义:内部实现了 __iter__() 方法的对象,返回一个迭代器对象。常见的可迭代对象包括列表、元组、集合、字典、字符串等。(注意:字典不能被直接迭代,需要用items()转换)
  • 特点
    • 可以使用 for 循环直接遍历。
    • 通过 iter() 函数可以将其转换为迭代器。

1.2 迭代器(Iterator)

  • 定义:内部实现了 __iter__()__next__() 方法的对象。
    • __iter__():返回迭代器对象本身。
    • __next__():返回下一个元素,若没有元素则抛出 StopIteration 异常。
  • 特点
    • 惰性计算:按需生成数据,适合处理大数据集。
    • 状态保存:记录当前遍历的位置,只能单向前进。
    • 一次性消耗:迭代器遍历完成后不可逆,需重新生成。

2. 迭代器的工作原理

2.1 如何使用迭代器?

  • 手动使用 iter()next()
    将可迭代对象转换为迭代器后,通过 next() 逐个获取元素:

    numbers = [1, 2, 3]
    iterator = iter(numbers)  # 转换为迭代器
    print(next(iterator))     # 输出: 1
    print(next(iterator))     # 输出: 2
    print(next(iterator))     # 输出: 3
    # print(next(iterator))  # 抛出 StopIteration 异常
    
  • 结合 try-except 处理异常
    手动控制迭代过程时,需捕获 StopIteration 异常:

    import sys
    my_list = [1, 2, 3]
    iterator = iter(my_list)
    while True:
        try:
            print(next(iterator))
        except StopIteration:
            sys.exit()
    

2.2 for 循环的本质

for 循环内部自动处理了迭代器的创建和异常捕获:

for item in [1, 2, 3]:
    print(item)

等价于:

it = iter([1, 2, 3])
while True:
    try:
        item = next(it)
        print(item)
    except StopIteration:
        break

3. 自定义迭代器

通过实现 __iter__()__next__() 方法,可以创建自定义迭代器。例如,生成一个数字序列:

class MyRange:
    def __init__(self, start, end):
        self.current = start
        self.end = end

    def __iter__(self):
        return self

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

# 使用自定义迭代器
for i in MyRange(1, 4):
    print(i)  # 输出: 1 2 3

4. 生成器(Generator)

生成器是迭代器的简化版本,通过 yield 关键字实现,适合生成大规模数据或无限序列。

4.1 生成器函数

def count_down(start):
    current = start
    while current > 0:
        yield current  # 暂停并返回当前值
        current -= 1

gen = count_down(3)
for num in gen:
    print(num)  # 输出: 3 2 1

4.2 生成器表达式

类似列表推导式,但使用圆括号:

gen = (x * x for x in range(3))
for num in gen:
    print(num)  # 输出: 0 1 4

4.3 生成器的高级用法

  • 惰性求值:适合处理大文件或无限序列。

    def read_large_file(file_path):
        with open(file_path) as f:
            for line in f:
                yield line.strip()
    
  • send()throw()close()

    • send(value):向生成器内部传递值。
    • throw(exception):抛出异常。
    • close():强制结束生成器。

5. 生成器的应用场景

5.1 处理大数据

  • 节省内存:生成器不会一次性加载所有数据到内存。

    def read_file_line_by_line(file_path):
        with open(file_path) as f:
            for line in f:
                yield line.strip()
    

5.2 无限序列

  • 生成器处理无限序列

    def fibonacci():
        a, b = 0, 1
        while True:
            yield a
            a, b = b, a + b
    
    for num in fibonacci():
        if num > 100:
            break
        print(num)  # 输出斐波那契数列直到100
    

5.3 自定义复杂迭代逻辑

  • 分页数据加载过滤条件动态调整等场景。

6. 迭代器与生成器的优缺点

特性 迭代器 生成器
实现方式 需手动实现 __iter____next__ 使用 yield 自动实现
内存占用 节省内存(惰性计算) 节省内存(按需生成)
代码简洁性 需编写类和方法 代码更简洁
适用场景 需要严格控制迭代逻辑 简单数据生成或无限序列

7. 常见问题

7.1 为什么迭代器只能单向遍历?

迭代器的设计原则是“单向性”,即只能从前往后遍历,且遍历完成后无法重置。若需重复使用,需重新生成迭代器。

7.2 如何判断对象是否是迭代器?

使用 collections.abc.Iterator 判断:

from collections.abc import Iterator
print(isinstance(iter([1, 2, 3]), Iterator))  # True

7.3 列表推导式 vs 生成器表达式

  • 列表推导式:一次性生成所有数据,占用内存。

    squares = [x * x for x in range(1000000)]
    
  • 生成器表达式:按需生成数据,节省内存。

    squares = (x * x for x in range(1000000))
    

8. 总结

  • 迭代器是Python中统一的遍历机制,适用于所有可迭代对象。
  • 生成器是迭代器的简化形式,通过 yield 实现惰性计算。
  • 应用场景:大数据处理、无限序列、内存优化等。
  • 核心优势:节省内存、代码简洁、灵活控制迭代逻辑。

通过掌握迭代器和生成器,可以编写更高效、优雅的Python代码,尤其是在处理大规模数据或复杂迭代逻辑时。

posted on 2025-06-29 09:02  burgess0x  阅读(18)  评论(0)    收藏  举报