【Python】生成器与迭代器

迭代器(iterator)

判断是否是迭代器和可迭代对象

from collections import Iterator  #迭代器
from collections import Iterable  #可迭代对象
 
print(isinstance(s,Iterator))     #判断是不是迭代器
print(isinstance(s,Iterable))       #判断是不是可迭代对象

明确以下三个概念:

**可迭代对象(Iterable)
迭代器(Iterator)
迭代(Iteration)**
(一)可迭代对象(Iterable)

(1) python内置的几种数据结构:字符串(str),列表(list),元组(tuple),字典(dict),集合(set)都是可迭代对象.

(2) Python中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法,那么它就是一个可迭代对象。简单说,可迭代对象就是能提供迭代器的任意对象。

from collections import Iterable    
class MyIter:
  def __init__(self):
    pass

  def __iter__(self):
    yield 1	             # __iter__()需要返回一个迭代器
    
a = MyIter()	         # 对象a就是一个可迭代的对象
print(isinstance(a,Iterable))       #判断是不是可迭代对象
#   True
(二) 迭代器(Iterator)

在python3中同时实现在__iter__()和__next__()两个魔法函数的对象,就是迭代器。其中__iter__()方法需要返回一个迭代器, 而__next__()方法返回下一个返回值或者StopIteration。

from collections import Iterator  #迭代器

class MyIter:
  def __init__(self):
    self.cnt = 0

  def __iter__(self):
    return self

  def __next__(self):      # 因为实现在__next__,所以自身就是一个迭代器,这里就可以返回自己
    return 1

s = MyIter()
print(isinstance(s,Iterator))     #判断是不是迭代器
#   True

迭代器可以通过next()方法不断重复获取下一个值,直到所有元素全部输出完之后,返回StopIteration才停止。

# 迭代器可以通过next()方法不断重复获取下一个值,直到所有元素全部输出完之后,返回StopIteration才停止。
def fun_print():
    for i in range(2):
        yield i+2
        
a = fun_print()
print(next(a))
print(next(a))
print(next(a))

结果为:

2
3
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-27-76648422ccff> in <module>
      9 print(next(a))
     10 print(next(a))
---> 11 print(next(a))

StopIteration: 

可迭代的对象不能使用next():

list1 = [1,2,5,3,5,6,44,8,5]
next(list1) 
# TypeError: 'list' object is not an iterator  

注: 对可迭代的对象,使用iter()方法,也会返回一个迭代器,如:

# 对可迭代的对象,使用iter()方法,也会返回一个迭代器,如:
a = iter([1, 2, 3, 4])
print(a)
# <list_iterator object at 0x000002B6BF679550>
(三) 迭代(Iteration)

用简单的话讲,它就是从某个地方(比如一个列表)取出一个元素的过程。当我们使用一个循环来遍历某个东西时,这个过程本身就叫迭代。

生成器(generator)

创建生成器的两种方法:生成器包括生成器表达式(类似于推导式)和生成器函数。

(一)生成器表达式

把一个列表生成式的[]中括号改为()小括号

# 创建生成器:  类似列表推导式
a = [i+1 for i in range(3)]  # 列表生成式
print(a)
b = (i+1 for i in range(3))  # 生成器
print(b)   
print(next(b)) # 使用next()函数获取下一个元素
print(next(b))
print(next(b))

结果为:

[1, 2, 3]
<generator object <genexpr> at 0x000002B6C0187900>
1
2
3
(二) 生成器函数
# 生成器函数
def myGen():
    x = range(1, 11)
    for i in x:
        yield i + 2      # 不用return语句, 使用yield 语句
        
print(myGen())
for x in myGen():
    print(x, end=",")

结果为:

<generator object myGen at 0x000002B6C0227660>
3,4,5,6,7,8,9,10,11,12,

生成器可以理解成一种特殊的迭代器。它和迭代器的区别在于,生成器并不是一上来就把所有值装载进内存,因而也不会占用大量的内存,只是在需要使用next()函数获取值的时候,才会取一个值返回,内存开销非常小。而是在运行时生成值。要想拿到每一个元素,就需要循环遍历或者使用。

(1)“for”循环进行循环遍历
b = (i+1 for i in range(3))  # 生成器
for i in range(3):# 一个“for”循环,
    print(i)
print(list(b))     #  传递给任意可以进行迭代的函数和结构。

结果为:

0
1
2
[1, 2, 3]

注:在一个操作中(如 for 循环)生成器不能读取迭代过的数据

(2)使用函数获取生成器元素
  next()                  系统自定义函数
   __next__()           生成器自定义函数
def fibon(n):
    a = b = 1
    for i in range(n):
        yield a
        a, b = b, a + b
a = fibon(4)         # 获取生成器对象
print(next(a))       # 系统函数: next(g)
print(a.__next__())   # 生成器自定义函数
print(a.__next__())   # 生成器自定义函数
'''
1
1
2
'''
生成器的应用实例:

#计算斐波那契数列的生成器:。

# generator version

def fibon(n):
    a = b = 1
    for i in range(n):
        yield a
        a, b = b, a + b

for x in fibon(10):
    print(x)     

''' 
1
1
2
3
5
8
13
21
34
55
'''

参考文献:
https://blog.csdn.net/weixin_40107510/article/details/93378198
https://blog.csdn.net/answer3lin/article/details/86493988

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何为xl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值