迭代器和生成器

迭代的概念:迭代就是可以被遍历的数据类型,也就是可以被一个一个取出来。

那么可迭代的类型有哪些?

from collections import Iterable

l = [1,2,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4}                

print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))

这里可以看出,元组,列表,字典,集合,包括字符串都是可迭代的。

1)为什么可以被迭代呢?

这就要说一下迭代的协议。

迭代的协议就是内部含有——lter——方法。

2)什么是迭代器?

print([1,2].__iter__())

结果
<list_iterator object at 0x1024784a8>

执行了list([1,2])的__iter__方法,我们好像得到了一个list_iterator,现在我们又得到了一个新名词

——iterator。

iterator的意思就是迭代器。

迭代器和可迭代的对面之间的区别就是在内容里面多了一个:__next__,这也是他们之间的最根本区别。

__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__()
print(item)

上路的可迭代对象如果遍历完,那么就会报错。有时候我们就有一些异常的办法把异常处理出去:

l = [1,2,3,4]
l_iter = l.__iter__()
while True:
    try:
        item = l_iter.__next__()
        print(item)
    except StopIteration:
        break

标准格式就是list.__next__(),这之前要看他是不是可迭代对象,如果不行就用__iter__()把他变成可迭代对象,然后在用next一个个遍历.

迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

3)range()是迭代器吗?

from collections import  Iterator
print(isinstance(range(100000000),Iterator))
print(isinstance(range(100),Iterator))
这里的isinstance是查看里面的值是什么数据类型,Iterator就是看看是不是迭代器。

4)迭代器有什么作用:最重要的一点就是可以节省内存空间。

Python中提供的生成器:

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

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

生成器Generator:

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

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

import time
def genrator_fun1():
    a = 1
    print(‘现在定义了a变量‘)
    yield a
    b = 2
    print(‘现在又定义了b变量‘)
    yield b

g1 = genrator_fun1()
print(‘g1 : ‘,g1)       #打印g1可以发现g1就是一个生成器
print(‘-‘*20)   #我是华丽的分割线
print(next(g1))
time.sleep(1)   #sleep一秒看清执行过程
print(next(g1))

初识生成器函数

这里有一些注意:首先运行一次genrator_fun1()的话,只会显示他是一个生成器,不会显示别东西,只有当你调用next(genrator_fun1())的话,他才会运行,但是你掉一次next他就只会运行到第一个yield,就不会再运行,只有你一下子调用2个next的时候,他才会一下子运行2个,并且把值返回到genrator_fun 里,下面谁接收的话,就给谁,另外,每一次调用后,当你重新调用的时候,程序又会重新从第一个开始运行。
ps:如果yield后面带了东西,当你运行到那的时候才会取出来。

下面是一些例子:

import tima
def func():
    f=open(filename)
    f.seak(0,2)
    while True:
        line=f.readline()
        if not line:
            time.sleep(0.2)
            continue
        else:
            yield  line
l=func()
for line in l:
    print(line)

#初识生成器二

def produce():
    """生产衣服"""
    for i in range(2000000):
        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:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 5:
        break

#到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。
#剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿

#初识生成器二

def produce():
    """生产衣服"""
    for i in range(2000000):
        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:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 5:
        break

#到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。
#剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿

衣服生产

def averager():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total += term
        count += 1
        average = total/count

g_avg = averager()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(5))

计算移动平均值(1)

平均值的计算

def init(func):  #在调用被装饰生成器函数的时候首先用next激活生成器
    def inner(*args,**kwargs):
        g = func(*args,**kwargs)
        next(g)
        return g
    return inner

@init
def averager():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total += term
        count += 1
        average = total/count

g_avg = averager()
# next(g_avg)   在装饰器中执行了next方法
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(5))

平均值带装饰器

下面是一个生成器yield   from 的一些应用

def gen1():
    for c in ‘AB‘:
        yield c
    for i in range(3):
        yield i

print(list(gen1()))

def gen2():
    yield from ‘AB‘
    yield from range(3)

print(list(gen2()))

yield from

列表表达式和生成器表达式:

之间的差别:列表表达式占系统内存空间较多,生成器几乎不占内存。

list=[x  for x in range(10000) ]---列表表达式

list=(x  for x in range(10000))---生成器表达式

时间: 2024-07-30 10:10:50

迭代器和生成器的相关文章

Python高级特性:迭代器和生成器 -转

在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了. 迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和next()方法.其中__iter__()方法返回迭代器对象本身:next()方法返回容器的下一个元素,在结尾时引发StopIteration异常. __iter__()和next()

Python的迭代器和生成器

先说迭代器,对于string.list.dict.tuple等这类容器对象,使用for循环遍历是很方便的就,在后台for语句对容器对象对象调用iteration()函数,这是python的内置函数,iter()会返回一个定义next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数.在没有后续元素是,调用next()会抛出一个StopIteration异常 上面说的都是python自带的容器对象,它们都实现了相应的迭代器方法,自定义类的遍历怎么实现,方法是

python——迭代器、生成器、装饰器

迭代器 迭代器规则 迭代:重复做一些事很多次,就像在循环中那样. 不仅可以对字典和序列进行迭代,还可以对其他对象进行迭代:只要该对象实现了__iter__方法. __iter__方法会返回一个迭代器(iterator),所谓的迭代器就是具有next方法(这个方法在调用时不需要任何参数)的对象.在调用next方法时,迭代器会返回他的下一个值.如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常. 注意:迭代器规则在3.0中有一些变化.在新的规则中,迭代器对象应

python高级编程之迭代器与生成器

# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #迭代器与生成器 #--------------------------------------- #迭代器基于2个方法 """ next:返回容器下一个项目 __iter__:返回迭代器本身 """ #通过内建函数和序列来创建 i=iter('abc') print i.next()#a print i.next(

python3 迭代器与生成器

pythom3 迭代器与生成器 迭代器'''迭代器是python最强大的功能之一,是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置对象迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问玩结束.迭代器只能往前不会后退.迭代器有两个基本方法:iter()和next().字符串,列表或元组对象都可用于创建迭代器: ''' list=[1,2,6,3] it=iter(list)#创建迭代器对象 print(next(it))#结果1 print(next(it))#结果2 print(

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

在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器.迭代器和生成器理解进行解释. 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思来谁就是对特定的建筑物内按照一定的思路和风格进行美化的一种行为,所谓“器”就是工具,对于python来说装饰器就是能够在不修改原始的代码情况下给其添加新的功能,比如一款软件上线之后,我们需要在不修改源代码和不修改被调用的方式的情况下还能为期添加新的功能,在python种就可以用装饰器来实现,同样在写

第四周Python--装饰器(迭代器、生成器)

---恢复内容开始--- 上节回顾: 编码:Python3中默认的是unicode,Python2中默认的是ASCII 区分:局部变量和全局变量 递归的特点: 1)规模减少 2)明确结束条件 3)效率低 函数式编程,不会有副作用,传递什么值就会有什么结果. 本节内容: 1.迭代器和生成器 2.装饰器 3.Json和Pickle序列化 4.软件目录结构规范 5.作业:ATM 1.迭代器&生成器 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束

Python学习之三大名器-装饰器、迭代器、生成器

Python学习之三大名器-装饰器.迭代器.生成器 一.装饰器     装饰,顾名思义就是在原来的基础上进行美化及完善,器这里指函数,所以说装饰器就是装饰函数,也就是在不改变原来函数的代码及调用方式的前提下对原函数进行功能上的完善.其核心原理其实是利用闭包.     格式 @关键字+装饰函数          被装饰函数()      注意:@行必须顶头写而且是在被装饰函数的正上方     按照形式可以分为:无参装饰器和有参装饰器,有参装饰器即给装饰器加上参数     以下示例是一个无参装饰器,

Python高手之路【九】python基础之迭代器与生成器

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

Python 从零学起(纯基础) 笔记 之 迭代器、生成器和修饰器

Python的迭代器. 生成器和修饰器 1. 迭代器是访问集合元素的一种方式,从第一个到最后,只许前进不许后退. 优点:不要求事先准备好整个迭代过程中的所有元素,仅仅在迭代到某个元素时才计算该元素,而在这之前或者之后,元素可以不存在或被销毁. 特点: 访问者是不需要关心迭代器内部的结构,仅需要通过next()方法不断去取下一个内容. 不能随机访问集合中的某个值,只能从头到尾依次访问. 访问到一半时不能往回退 便于循环比较大的数据集合,节省内存 1 names = iter(['alex','ja