一、迭代器:iterable(可迭代的,可重复的)
就是更新重复的过程,每次的迭代都必须基于上一次的结果,内部都是基于for 循环原理
为什么要用迭代器:迭代器提供了一个不需要按索引取值的方式
只是简单的重复,没有更新内容这不算是迭代 n = 0 while True: print(n)
l=[1,2,3,4,5] count=0 while count<len(l): print(l[count]) count+=1
二、什么是可迭代对象
可迭代对象指的是内置有__iter__方法的对象,例如:atr 字符串 list 列表 tuple 元组 set 集合 dict 字典
文件对象也是(执行内置的__iter__之后还是本身,没有任何变化,文件对象本身就是迭代器对象
l2=(1,2,3) res=l2.__iter__() print(res)
执行的结果:<tuple_iterator object at 0x000001E48B5BE940>
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<end: yield start start+=step for j in my_range(1,10):# 循环打印输出1—10 print(j)
六、了解: yield表达式的形成
利用函数调用的特性和yield的本质在函数中的运用
def inner(name): print('my name is %s'%name) while True: like=yield # 如果不传值就结束程序 print('i like%s'%like) def func(): pass res=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—10 res1=(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+i def test(): for i in range(4): yield i g=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.12 print(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方法的时候,又从当前位置继续往下走。