python之 迭代器,生成器

什么叫跌代

可以将某个数据集合内的数据一个一个挨着取出来就叫做跌代。

迭代器协议:

可以被跌代要满足的要求叫做可迭代协议,可迭代对象必须提供一个next的方法,执行该方法要么返回跌代中的下一项,要么就引起一个StopIteration异常,以终止跌代(跌代只能往后走,而不能往前退)

python中的for循环:

for循环的本质就是遵循迭代器协议去访问对象,for循环可以遍历(字符串,列表,元祖,字典,集合,文件对象)这些对象都是不可迭代对象,只不过在for循环时,调用了他们内部的—iter—方法,把他们变成可迭代对象,然后for循环调用可迭代对象的—next—方法去取值,而且for循环会捕捉stoplteration异常,以终止跌代。

#while 循环模拟for循环
diedai_1 = l.__iter__()
while True :
    try:#错误处理机制
        print(diedai.__next__())
    except StopIteration:#自动捕捉stopiteration错误,防止报错
        print("跌代完成")
        break

for循环为我们提供了一个不依赖索引取值的方法,基于跌代器协议提供了一个统一的可以遍历所有对象的方法,在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议去实现循环访问,这样所有的对象都可以通过for循环来遍历了。

什么叫迭代器:

拥有__iter__方法和__next__方法的对象就叫迭代器

l = [1,2,3,4]
l_iter = l.__iter__()
item = l_iter.__next__()#每次取一个值
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()
print(item)
item = l_iter.__next__()#没有值了报错异常StopIteration
print(item)

迭代器的优点:提供一种不依赖索引的取值方式。

       惰性计算,节省内存。

迭代器的缺点:取值不如按照索引取值方便。

       一次性的,只能往后走,不能往前退。

         无法获取长度。

生成器:

什么是生成器:可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象。

Python中提供的生成器:

1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

生成器Generator:

  本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)

  特点:惰性运算,开发者自定义

生成器函数:


一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中的返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行的结束。

包含yield关键字的函数就叫生成器函数
def genrator_fun1():
    a =1
    print("现在定义了a变量")
    yield  a
    b = 2
    print("现在又定义了b变量")
    yield b
g1 = genrator_fun1()
print(g1)
print(next(g1))
print(next(g1))

生成器有什么好处呢,不会一下子在内存中生成太多数据,假如生产一批200000万件的衣服,一批一批的拿,就可以用生成器函数来表示。

def produce():
    for i in range(20000):
        yield "生产了第%s件衣服"%i
product_g = produce()
print(product_g.__next__())#第一件衣服
print(product_g.__next__())#第二件
print(product_g.__next__())#第三件
num = 0
for i in product_g:#取30件
    print(i)
    num += 1
    if num == 30:
        break

更多应用

import time
def tail(filename):
    f = open(filename)
    f.seek(0,2)#从文件末尾算
    while True:
        line = f.readline()#读取文件中新的文本行
        if not line:
            time.sleep(0.1)
            continue
        yield
tail_g = tail("tmp")#“tmp”文件名
for line in tail_g:
    print(line)

生成器监听文件输入

#模拟平均工资
def average():
    total = 0
    day = 0
    average = None
    while True:
        term = yield average#相当于return了一个average
        total += term#总工资等于这几天所有工资的和
        day += 1#天数过一天就加一
        average = total/day
avg = average()
next(avg)#这里是激活生成器,avg.send()什么值都不传,和next的效果一样
print(avg.send(10))#send有两个作用,传值和寻找下一个yield(next)
print(avg.send(20))

计算移动平均值

生成器想要运行,必须在调用的时候用next()方法来激活它,那么能不能不激活直接拿来就可以用呢,我们需要给生成器加上一个装饰器就可以解决这个问题了。

def init(func):
    def inner(*args,**kwargs):
        g = func(*args,**kwargs)#将函数average传入func()用g来接受返回值
        next(g)#在这里激活了生成器
        return g
    return inner
@init
def average():
    total = 0
    day = 0
    average = None
    while True:
        term = yield average
        total += term
        day += 1
        average = total/day
avg = average()
#next(avg),用装饰器执行了next方法
print(avg.send(10))
print(avg.send(100))
print(avg.send(150))

装饰器装饰生成器

yield from

def  gen1():
    for c in "AB":
        yield c
    for i in range(3):
        yield i
print(list(gen1()))#[‘A‘, ‘B‘, 0, 1, 2]
def gen2():
    yield from "AB"
    yield from range(3)
print(list(gen2()))#[‘A‘, ‘B‘, 0, 1, 2]

列表推导式和生成器解析式

egg_list = ["鸡蛋%s"% i for i in range(10)]
print(egg_list)#列表解析式
laomuji = ("鸡蛋%s"% i for i in range(10))
print(laomuji)#生成器表达式,就是将列表解析式的中括号[]换成()

列表解析式的[]换成()就是生成器表达式,列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式比列表解析式更节省内存空间。python不但使用迭代器协议,让for循环变得更加通用,大部分内置函数,也是使用迭代器协议访问对象的。

总结:

可迭代对象:拥有__iter__()方法,特点就是惰性计算,节省内存。

迭代器:Iterator 拥有__iter__方法和__next__方法

生成器:Generator  本质即使迭代器  特点:延迟计算,一次返回一个结果,这对于大量的数据处理,将会非常有用。

时间: 2024-10-10 02:32:00

python之 迭代器,生成器的相关文章

python 【迭代器 生成器 列表推导式】

python [迭代器  生成器  列表推导式] 一.迭代器 1.迭代器如何从列表.字典中取值的 index索引 ,key for循环凡是可以使用for循环取值的都是可迭代的可迭代协议 :内部含有__iter__方法的都是可迭代的迭代器协议 :内部含有__iter__方法和__next__方法的都是迭代器 print(dir([1,2,3])) lst_iter = [1,2,3].__iter__() print(lst_iter.__next__()) print(lst_iter.__ne

python之迭代器生成器和内置函数,匿名函数

今天学习了迭代器生成器以及内置函数和匿名函数,说实话有些懵圈,有些难度了. 一.迭代器和生成器 1.如何从列表.字典中取值的: index索引 for循环 凡是可以使用for循环取值的都是可迭代的 (1)可迭代协议:内部含有__iter__方法的都是可迭代的 (2)迭代器协议:内部含有__iter__方法和__next__方法的都是迭代器 什么是可迭代的:内部含有__iter__方法的都是可迭代的 什么是迭代器:迭代器=iter(可迭代的),自带一个__next__方法 可迭代最大的优势:节省内

【Python】 迭代器&生成器

迭代器 任何一个类,只要其实现了__iter__方法,就算是一个可迭代对象.可迭代对象的__iter__方法返回的对象是迭代器,迭代器类需要实现next方法.一般来说,实现了__iter__方法的类肯定还会顺便实现next方法,也就是说这个类既是一个可迭代对象也是个迭代器. 一个迭代器ite可用ite.next()方法来返回其定义好的以某种算法找到的下一个元素,内建的iter(...)函数可把可迭代对象转化为迭代器.最常见的利用可迭代对象和迭代器的就是for语句了: for item in it

[python]--迭代器,生成器补充

在python中,list,string,dict都是可迭代对象,可以通过for语句遍历. 迭代器 迭代器对象要求支持迭代器协议的对象,在python中,支持迭代器协议就算实现对象的__iter__()和next()方法.其中__iter__()方法返回迭代器对象本身; next()方法返回容器的下一个元素,在结尾时引发StopIteration异常 __iter__()和next()方法 这两个方法是迭代器最基本的方法,一个用来获得迭代器对象,一个用来获取容器中的下一个元素. 对于可迭代对象,

python中的生成器和迭代器

1. 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 1.1 使用迭代器的优点 对于原生支持随机访问的数据结构(如tuple.list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值).但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式. 另外,迭代器的一大优点是不要求事

python 迭代器 生成器 (转)

转帖: 原文写的不错! 原文地址:http://www.cnblogs.com/kaituorensheng/p/3826911.html#_label0 阅读目录 1. 迭代器 2. 生成器 3. 参考 回到顶部 1. 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 1.1 使用迭代器的优点 对于原生支持随机访问的数据结构(如tuple.list),迭代器和经典fo

Python的迭代器与生成器

Python中的生成器和迭代器方便好用,但是平时对生成器和迭代器的特性掌握的不是很到位,今天将这方面的知识整理一下. 迭代器 为了更好的理解迭代器和生成,我们需要简单的回顾一下迭代器协议的概念. 迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象

Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 先定义一个基本的装饰器: ########## 基本装饰器 ########## def orter(func):    #定义装饰器     de

Python之迭代器、生成器、装饰器和递归

一.迭代器&生成器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁.这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件 特点: 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容 不能随机访问集合中的某个值 ,只能从头

4.python的迭代器与生成器

一.什么玩意是迭代器? 先说说什么是迭代吧,迭代就是一件事情重复很多次,比如说for循环. for循环可以对一切有__iter__方法的对象进行迭代,那么什么是__iter__方法呢? 一个对象是否可迭代,全都取决于这个对象是否有__iter__方法,调用对象的__iter__方法,就回返回一个迭代器,这个迭代器一定具有next方法,在调用这个迭代器的next方法时,迭代器就回返回它的下一个值,当迭代器中没有值可以返回了,就回抛出一个名为StopIteration的异常,停止迭代. 迭代器还有个