博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迭代器和生成器
阅读量:5290 次
发布时间:2019-06-14

本文共 4789 字,大约阅读时间需要 15 分钟。

一、迭代器:iterable(可迭代的,可重复的)

      就是更新重复的过程,每次的迭代都必须基于上一次的结果,内部都是基于for 循环原理

  为什么要用迭代器:迭代器提供了一个不需要按索引取值的方式

只是简单的重复,没有更新内容这不算是迭代n = 0 while True:     print(n)
l=[1,2,3,4,5]count=0while count
 
上述例子就是一个完整的迭代过程

 二、什么是可迭代对象

  可迭代对象指的是内置有__iter__方法的对象,例如:atr 字符串   list 列表  tuple 元组   set 集合    dict  字典 

       文件对象也是(执行内置的__iter__之后还是本身,没有任何变化,文件对象本身就是迭代器对象

l2=(1,2,3)res=l2.__iter__()print(res)      执行的结果:
l3={
'a':1}l3.__iter__()l4={
'a','b'}l4.__iter__()
f=open('03.txt','w',encoding='utf-8')
f.__iter__()

  可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象

三、迭代器对象:

  迭代器对象:可以用next获取下一个值(说明实现了next方法),但是每个值只能获取一次,单纯的迭代器没有实现iter魔法函数,所以不能使用for循环

  指的是即内置有__iter__又内置有__next__方法的对象,必须同时满足这两个条件

        迭代器一定是可迭代对象,而可迭代对象不一定是迭代对象

  文件类型是迭代器对象 

f=open('03.txt','w',encoding='utf-8') res1=f.__iter__() res2=f.__exit__() print(res1,res2)

1:迭代器的取值调用  __next__

p=[1,2,3,4,5]iter_p=p.__iter__() # 先生成一个迭代器对象,才可以调用迭代器的取值 调用 ——next——print(iter_p._next_())
# 次数超过容器类型 print(iter_l.__next__()),如果取完了 直接报错
d = {
'name':'gason','password':'123','hobby':'write'} # 将可迭代对象d转换成迭代器对象,才可被调用 iter_d = d.__iter__() #迭代器对象的取值 必须用__next__ print(iter_d.__next__()) print(iter_d.__next__()) print(iter_d.__next__()) print(iter_d.__next__()) # 取完了 报错StopIteration

 

打开文件:f1=open('03.txt','r',encoding='utf-8')iter_f=f1.__iter__()print(iter_f is f1)

注:迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身

  迭代器取值的特点: 只能依次往后取  不能倒退  取完就会报错

2、迭代取值的有缺点

    优点:
        1.不依赖于索引取值
        2.内存中永远只占一份空间,不会导致内存溢出
   
    缺点:
        1.不能够获取指定的元素
        2.取完之后会报StopIteration(停止迭代)的错

 

四、for 循环的本质:

    1:将in后面的可迭代对象调用__iter__转换成迭代器对象

    2:调用了__next__迭代的取值方法

    3:内部有异常捕获StopIteration(停止迭代)超出了范围,,当__next__报这个错,自动结束循环

l=[1,2,3,4]res=map(lambda x:x+1,l)print(res.__next__())print(res.__next__())print(res.__next__())print(res.__next__())

 

五、生成器:人为自定义实现迭代的功能就叫生成器 

关键字:  yield  

函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行 ,程序中遇到yield会暂停运行等待调入参数 

def func():    print('one')    yield  12   #程序调用函数执行到 yeild 后就会终止    print('two')    yield    print('three')res=func()print(res.__next__())结果>>>one >>>12如果yrilde 后面不传参数的话 返回 None

 

 

  利用关键字‘yiled’ 用函数实现 range 原理:

print(range(1,10))def my_range(start,end,step=1):    while start

六、了解:   yield表达式的形成

    利用函数调用的特性和yield的本质在函数中的运用

def inner(name):    print('my name is %s'%name)    while True:        like=yield  # 如果不传值就结束程序        print('i like%s'%like)def func():    passres=inner('kevin')res.__next__()# 必须先将代码运行至yiled 才能够为其传值res1=res.inner('write') # 调用__next_才能执行yiled后面的语句print(res)

 

yield

    1.帮你提供了一种自定义生成器方式
    2.会帮你将函数的运行状态暂停住
    3.可以返回值

 

与return之间的区别

    相同点:都可以返回值,并且都可以返回多个
    不同点:
        yield可以返回多次值,而return只能返回一次函数立即结束
        yield还可以接受外部传入的值

 七、生成器表达式:

    把列表解析的 [] 换成 () 得到的就是生成器表达式

          #生成器表达式 sum(i for i in range(100000000))#几乎不占内存

res=[i for i in range(1,10) if i!=4]print(res)#全部打印输出1—10res1=(i for i in range(1,10000) if i!=4) #生成器表达式print(res1) # next=res.__iter__()print(res1.__next__()) print(res1.__next__()) print(res1.__next__()) print(res1.__next__())# 必须通过触发—next—才会触发

 

生成器面试题:

def demo():    for i in range(4):        yield i  # i=[0,1,2,3]  # 遇到—next--才会触发执行 g=demo()g1=(i for i in g)  #  for 循环取值赋值给g1,已经取完i中的内存地址g2=(i for i in g1)print(list(g1))print(list(g2))结果:>>>[0,1,2,3]>>>[]

 

def add(n,i):    return n+idef test():    for i in range(4):        yield ig=test()for n in [1,10]:    g=(add(n,i) for i in g)    # 第一次for循环g=(add(n,i) for i in test())    # 第二次for循环g=(add(n,i) for i in (add(n,i) for i in test()))print(n)res=list(g)"""for i in (add(10,i) for i in test()):  会执行所有的生成器内部的代码    add(n,i)"""

结果输出是:20 21 21 23

循环执行完第一次 n=10

八、内置函数: Python中提供了68个内置函数

 

 常用的内置函数执行:

 

1.abs:绝对值

i=-1.12print(abs(i))  #  负数转正

 

2.all(全部)  any (部分)

l = [0,1,0] print(all(l))  # 只要有一个为False就返回False print(any(l))  # 只要有一个位True就返回True

 

3.locals(当地)  美 ['loʊklz]   globals(全球)

def index():    username = '我是局部名称空间里面的username'    print(locals())  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字    #print(globals())  # 无论在哪 查看的都是全局名称空间地址index()

 

4. bin(二进制)  oct(八进制) hex(十六进制)  int(整形)

print(bin(10)) # 转换为二进制 print(oct(10)) print(hex(10))print(int('0b1010',2))  #二进制转换为十进制

 

 

5、布尔值bool  只有两种结果True False       True= 0,空,None

6、bytes  打印字节数

7、callable     adj.  可随时支取的,请求即付的,随时可偿还的

可调用的(可以加括号执行相应功能的) l = [1,2,3] def index():     pass print(callable(l)) print(callable(index))

8、chr  ord   字符的转换

print(chr(97))  # 将数字转换成ascii码表对应的字符 print(ord('a'))  # 将字符按照ascii表转成对应的数字

9、divmod  分页器

print(divmod(101,10))  # 爬虫

10、enumerate 枚举

l = ['a','b']for i,j in enumerate(l,1):# 枚举按编号取值 1是初始值,不写默认为0    print(i,j)结果:>>>1  a>>>2   b应用场景是购物车 按序号选功能

11、 format 三种玩法:

 {}占位   #格式化输出,和%s %d一样的原理
{index} 索引 
 {name} 指名道姓  # 字典中用到

12、type isinstance 判断数据类型

n = 12 print(type(n))print(isinstance(n,list))  # 判断对象是否属于某个数据类型

13、pow 幂运算

print(pow(2,3))   >>> 2**3

14、help 查看内置原理

15、print(round(3.4))  把…四舍五入;

 

生成器:函数中只要有yield,这个函数就会变成生成器。每次运行到yield的时候,函数会暂停,并且保存当前的运行状态,返回返回当前的数值,并在下一次执行next方法的时候,又从当前位置继续往下走。

转载于:https://www.cnblogs.com/Gaimo/p/11189754.html

你可能感兴趣的文章
关于Mysql select语句中拼接字符串的记录
查看>>
动态规划 例子与复杂度
查看>>
安装webpack-dev-server后,npm run dev报错
查看>>
[BZOJ4567][SCOI2016]背单词(Trie+贪心)
查看>>
15软工课后作业01—15100120
查看>>
git回退到某个版本并提交
查看>>
查看oracle数据库的连接数以及用户
查看>>
简单几行js实现tab选项切换效果
查看>>
关于更改滚动条样式
查看>>
【数据结构】栈结构操作示例
查看>>
中建项目环境迁移说明
查看>>
[转帖] Oracle 关闭自动收集统计信息
查看>>
三.野指针和free
查看>>
VIO的Bundle Adjustment推导
查看>>
activemq5.14+zookeeper3.4.9实现高可用
查看>>
asp.net FileUpload控件文件格式的判断及文件大小限制
查看>>
angular(1.5.8)
查看>>
h5的video标签支持的视频格式
查看>>
大数据没那么重要
查看>>
TCP/IP详解学习笔记(3)IP协议ARP协议和RARP协议
查看>>