python的generator、iterator、iterable

本文深入探讨了Python中的迭代器和生成器。迭代器是节省内存的对象,可以直接用于for循环,例如list、dict等可迭代对象。而生成器是迭代器的一种,可以通过yield关键字创建,可以在for循环中使用或通过next()函数逐次获取值。斐波那契数列的生成器示例展示了其工作原理。for循环本质上是调用next()函数的连续过程。理解这些概念对于高效利用Python处理大量数据至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##python的高级特性----迭代器 参考:python的高级特性----迭代器
迭代器主要就是节省内存

  1. 在python中可以直接作用于for循环的数据类型有以下几种:
    (1)集合类型的数据:listtupledictsetstr
    (2)generator: 包括生成器带yield 的 generator function
    上述对象可以直接作用于for循环,统称为可迭代对象:iterable,我们可以通过isinstance() 判断一个对象是否是Iterable对象:
isinstance((x*x for x in range(1,5)), Iterator)   # True, (x*x for x in range(1,5))并不是生成tuple,而是生成generator
  1. 生成器generator不但可以用for循环,还可以被next()函数或者__next__()内置方法不断获取下一个值,直到最后抛出StopIteration错误。可以被next()函数或者__next__()内置方法不断返回下一个值的对象成为迭代器Iterator生成器generator都是迭代器Iterator,但是Iterable对象不一定是迭代器Iterator,如listdictstrtupleset都不是迭代器Iterator,想要用next()函数或者__next__()内置方法得先通过iter()方法将其变成迭代器Iterator
# 斐波那契数列
a = [1, 2, 3, 4, 5]
a = iter(a)
print(type(a))   #  >>> <class 'list_iterator'>
for i in range(5):
   print(a.__next__())   # >>> 1, 2, 3, 4, 5
# 这里有个问题,如果把`iter(a)`声明在for循环里,则会出现问题,只打印第一个值,应该是每次for循# 环都会`iter(a)`一次,所以才会这样,类似于局部变量
a = [1, 2, 3, 4, 5]
print(type(a))   #  >>> <class 'list_iterator'>
for i in range(5):
   print(iter(a).__next__())   # >>> 1, 1, 1, 1,
   ```
```python
def fab(max):  # fab 是一个 generator function
   n = 0
   a, b = 0, 1
   while(n < max):
       yield b
       a, b = b, a + b
       n = n + 1

a = fab(5)   # >>> fab(5) 是一个 generator

for i in range(5):
   print(a.__next__())   # >>> 1, 1, 2, 3, 5
  1. generator__next__()内置方法。迭代器Iteratornext()函数,python3中next()函数用法为next(iterator)
  2. for循环本质上就是不断调用next()函数实现的
for x in [1,2,3,4,5]:
       pass
   等同于
   it = iter([1,2,3,4,5])
   while True:
       try:
           x = next(it)
       except StopIteration:       #遇到StopIteration时则退出循环。
           break

================================================
小结:
1、可以for循环的对象都是Iterable ,可迭代对象。
2、可以作用于next()函数或者__next__()的对象都是Iterator迭代器next()函数其实就是在调用__next__()方法。Iterator迭代器是一个惰性计算的序列。
3、集合数据类型如dictlisttuple等对象是Iterable,但是不是Iterator,但是可以通过iter()函数获得Iterator对象,iter()函数其实就是在调用__iter__()方法。需要传入一个Iterable参数,函数的返回值是一个iterator对象

### Python迭代器的二次遍历方法与实现 在Python中,迭代器(Iterator)是一个遵循迭代协议的对象,它支持`__iter__()`和`__next__()`方法。然而,迭代器通常只能被遍历一次,当所有元素都被访问后,再次调用`__next__()`会抛出`StopIteration`异常[^2]。因此,如果需要对迭代器进行二次遍历,必须采取特定的方法。 以下是一些常见的实现方式: #### 方法一:将迭代器转换为可重复使用的容器类型 通过将迭代器中的元素存储到列表、元组等容器类型中,可以实现多次遍历。这种方法简单直接,但可能占用更多内存。 ```python # 示例代码 iterator = iter([1, 2, 3]) container = list(iterator) # 将迭代器转换为列表 for item in container: # 第一次遍历 print(item) for item in container: # 第二次遍历 print(item) ``` 此方法适用于数据量较小或内存允许的情况下[^4]。 #### 方法二:重新创建迭代器 如果原始数据源是可迭代对象(Iterable),可以通过调用`iter()`函数重新生成一个新的迭代器实例。这种方式不会增加额外的内存开销,但要求原始数据源必须是可重复访问的。 ```python # 示例代码 iterable = [1, 2, 3] iterator1 = iter(iterable) # 创建第一个迭代器 for item in iterator1: # 第一次遍历 print(item) iterator2 = iter(iterable) # 重新创建第二个迭代器 for item in iterator2: # 第二次遍历 print(item) ``` 此方法依赖于原始数据源是否支持多次迭代[^3]。 #### 方法三:使用生成器表达式或生成器函数 生成器(Generator)是一种特殊的迭代器,可以通过生成器表达式或定义生成器函数来实现数据的按需生成。如果需要多次遍历生成器的结果,可以将其转换为列表或其他容器类型,或者重新调用生成器函数。 ```python # 示例代码 def generator_function(): yield 1 yield 2 yield 3 gen1 = generator_function() # 调用生成器函数 for item in gen1: # 第一次遍历 print(item) gen2 = generator_function() # 再次调用生成器函数 for item in gen2: # 第二次遍历 print(item) ``` 生成器的优点在于其惰性求值特性,适合处理大数据流或无限序列[^1]。 #### 方法四:使用`itertools.tee` `itertools`模块提供了`tee`函数,可以从一个迭代器中派生出多个独立的迭代器。需要注意的是,`tee`会缓存部分数据以支持多路迭代,因此可能会增加内存消耗。 ```python from itertools import tee # 示例代码 iterator = iter([1, 2, 3]) iterator1, iterator2 = tee(iterator) # 派生两个独立的迭代器 for item in iterator1: # 第一次遍历 print(item) for item in iterator2: # 第二次遍历 print(item) ``` `tee`适合用于复杂场景下的多路遍历需求。 --- ### 注意事项 - 如果迭代器来源于不可重复访问的数据源(如文件流或网络请求),则无法直接重新创建迭代器,需要先将数据缓存到内存中。 - 使用`tee`时需注意内存消耗问题,尤其是在处理大数据集时[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值