迭代器和生成器函数

引入:

l = [1,2,3,4,5]
s = {1,2,3,4}
for i in l:
    print(i)

如果代码是:

for i in 50:
    print(i)

这个运行不了。输出结果是 ‘int‘ object is not iterable

iterable是可迭代的意思。

哪些可以迭代呢?这些可以str、list、tuple、set、dic等

可迭代的标志是  _iter_。

那我们如何判断是否可以迭代呢?

print(‘__iter__‘ in dir([1,2,3]))

双下划线的内置方法一般不用这种方法调用:

print(next(l.__iter__()))

而是用这种方法调用:

print(next(iter(l)) )

小结:

(1)可迭代协议——凡是可迭代的内部都有一个__iter__方法

(2)迭代器里既有iter方法,又有next方法 ——迭代器协议

(3)通过iter(o)得到的结果就是一个迭代器

(4)0是可迭代的对象

判断是否是迭代器和可迭代对象的方法:

from collections import Iterable
from collections import Iterator
s = ‘abc‘
print(isinstance(s,Iterable))
print(isinstance(s,Iterator))
print(isinstance(iter(s),Iterator))

生成器包括两个方面:生成器函数和生成器表达式

生成器有两种:一种是调用方法直接返回的,一种是可迭代对象通过执行iter方法得到的,迭代器有的好处是可以节省内存。

如果在某些情况下,我们也需要节省内存,就只能自己写。我们自己写的这个能实现迭代器功能的东西就叫生成器。

python中内置的生产器:

(1)生成器函数:关键字是yield,yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次继续运行。

(2)生成器表达式:类似于列表推导式,但是返回的是一个对象而不是一个结果列表 ,即惰性运算。

生成器函数:一个含有yield的函数就是生产器函数。通过调用返回的是一个对象,而不是结果列表。通过每一次对这个对象的请求就得到一个值def func():    print(‘aaaa‘)

    a=1
    yield a#返回第一个值
    print(‘bbbbb‘)
    yield 12#返回第二个值
    print(‘cccccc‘)
    yield 56#返回第三个值
ret=func()#拿到一个生成器
print(next(ret))#取第一个值
print(next(ret))#ret不可以用func替代
print(next(ret))

生成器例子:可以监听一个文本输入的文本

import time
def tail(filename):
    with open(filename) as f:
        f.seek(0,2)
        while True:
            line=f.readline()
            if not line:
                #time.sleep()
                continue
            yield line
for line in tail(‘监视文件‘):
    print(line,end=‘‘)

可以计算移动平均值的例子:

def averager():
    total=0
    day=0
    average=0
    while True:
        day_num=yield average
        total+=day_num
        day+=1
        average=total/day
avg=averager()#直接返回生成器
next(avg)#激活生成器avg.sed(),什么都 不send和next效果一样
print(avg.send(10))
print(avg.send(15))
print(avg.send(80))

装饰器版计算移动平均值的例子:

def wrapper(func):
    def inner(*arge,**kwargs):
        ret=func(*arge,**kwargs)
        next(ret)
        return ret
    return inner
@wrapper
def averager():
    total=0
    day=0
    average=0
    while True:
        day_num=yield average
        total+=day_num
        day+=1
        average=total/day
avg=averager()#直接返回生成器
# next(avg)#激活生成器avg.sed(),什么都 不send和next效果一样
print(avg.send(10))
print(avg.send(15))
print(avg.send(80))

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

列表推导式:(两个代码实现相同的效果)

for i in range(100):
    print(i*i)
l=[i*i for i in range(100)]
print(l)
l = [{‘name‘:‘v‘,‘age‘:28},{‘name‘:‘v‘}]
name_list = [dic[‘name‘] for dic in l]
print(name_list)

生成器表达式:

l=(i*i for i in range(100))
print(next(l))
print(next(l))
print(next(l))
print(next(l))
l = [{‘name‘:‘v1‘,‘age‘:28},{‘name‘:‘v2‘}]
name_list_generator = (dic[‘name‘] for dic in l)
#print(name_list_generator)
print(next(name_list_generator))
print(next(name_list_generator))

我们会发现列表推导式和生成器表达式除了括号不一样外都一样。列表推导式是中括号,生成器表达式是小括号。

区别:列表推导式是把所有的数据都一起算出来,而生成器表达式是一种惰性运算你请求一次给你一个数据。因此相比较来说生成器表达式更节省内存。

Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和:

print(sum(x**2 for x in range(3)))

而不用多此一举先构造一个列表啦

print(sum([x**2 for x in range(3)]))

总结:

可迭代对象:

拥有_inter_方法

惰性计算

像str、list、tuple、set、dic等

迭代器:

拥有_inter_方法和next方法

像:iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),reversed(list_o),map(func,list_o),filter(func,list_o),file_o

特点: 可以用for循环、 可以节省内存、只能用一次

生成器:本质是迭代器(同时拥有_inter_和next方法)

是开发人员自己定义的迭代器

优点:

1.延迟计算,你请求一次他给你返回一个结果。他不会给你返回所有的结果,不会大量占据内存

2.代码简洁,容易读

时间: 2024-10-24 13:13:30

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

1.17 Python基础知识 - 迭代器和生成器初识

可循环迭代的对象称为可迭代对象,迭代器和生成器函数是可迭代对象. 列表解析表达式:可以简单高效处理一个可迭代对象,并生成结果列表 示例代码: [ i ** 2 for i in range(10) ] #输出结果 [0,1,4,9,16,25,36,49,64,81] 生成器表达式:可以简便快捷地返回一个生成器.生成器表达式的语法和列表解析式基本一样,只不过是将[]替换成() 生成器的数据只有在调用时才生成 示例代码: a = ( i ** 2 for i in range(10)) print

python函数、装饰器、迭代器、生成器

5月21日,请假结婚,然后性格惰性来了,不怎么想看视频和笔记,性格中的弱点开始出现,开始做的不错,渐渐开始松懈,直至放弃--- 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象:  函数是第一类对象,即函数可以当作数据传递,它的应用形式也被称为高阶函数,函数的特性如下: a. 可以被引用 1 # def foo(): 2 # print('from foo') 3 # 4 # func = foo

函数4—迭代器与生成器

基础概念迭代器: 为什么: 提供了一种不依赖于索引的取值方式,如字典,集合,文件等没有索引的类型需要循环取出元素 迭代器是惰性计算,更节省内存,迭代器在内存中只是一个内存地址,一次只取一个值 缺点:永远无法获取迭代器的长度,使用不如列表索引取值灵活 一次性的,只能往后取值 可迭代的:对象本身有__iter__方法 i = iter(n) or i = n.__iter__() i 为n的迭代器 next(i) or i.__next__() 利用迭代器输出内容,一次输出一个 生成器: 定义: 函

重修课程day12(函数之迭代器和生成器)

一  迭代器 集合的目的:去重,关系运算. # a={1,2,3,4,5,6,7} # b={41,52,5,26,7,4,2,9,} # print(a-b) isinstance:判断数据的类型,还可以判断是否可迭代. iterable:形容词  可迭代的:from collections import Iterable:用来检测一个对象是否可以迭代. # from collections import Iterable # print(isinstance('fadda',Iterable

python基础-------迭代器,生成器,协程函数

1,迭代器协议: 1.1 迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 1.2. 可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 1.3. 协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象 2,迭代器: 1.1:为什么要用迭代器: 1.2 优点:迭代器提

python迭代器和生成器(3元运算,列表生成式,生成器表达式,生成器函数)

1.1迭代器 什么是迭代器: 迭代器是一个可以记住遍历的位置对象 迭代器对象从集合的第一个元素元素开始访问,直到所有元素被访问完结束,迭代器只能往前不会后退. 迭代器有两个基本方法:iter ,next 方法 内置函数iter(),next()  本质上都是用的对象.__iter__(),__next__()的方法 内置函数 iter(iterable),表示把可迭代对象 变成迭代器(iterator) 内置函数next(iterator) ,表示查看下一次迭代的值(当然也可以用 iterato

python函数:迭代器和生成器

python函数:迭代器和生成器 迭代器和生成器是函数中的一大重点,务必掌握,何为迭代?何为迭代器? 预习: 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕(使用生成器) 一.迭代器 for i in 50:     print(i) #运行结果: # Traceback (most recent call last): #   File "G:/python/python代码/八月/day2 迭代器生成器/3迭代器.py", line 8, in &

python基础----迭代器、生成器、协程函数

一.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象. 二,为什么要用迭代器 优点: 1:迭代器提供了一种不依赖于索引的取值方式,

python函数(5):迭代器和生成器

迭代器和生成器是函数中的一大重点,务必掌握,何为迭代?何为迭代器? 预习: 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕(使用生成器) 一.迭代器 for i in 50: print(i) #运行结果: # Traceback (most recent call last): # File "G:/python/python代码/八月/day2 迭代器生成器/3迭代器.py", line 8, in <module> # for i i