一.迭代器
1.什么是迭代器
迭代:更新换代的过程,前一次循环的终止条件是后一次循环的初始条件。
迭代器:迭代取值的过程。
2.为什么要用迭代器
迭代器提供了一种不依赖索引取值的方式
3.怎么用迭代器
可迭代对象(iterable) :有内置方法__iter__ ps:补充:针对双下线开头双下划线结尾的方法,推荐读:双下+方法名
基本类型中的可迭代对象有:str,tuple,list,dict,set和文件对象(文件对象本身就是一个迭代器对象)
str = "12123" lis = [1,2,3,4,5] tup = (1,2,3,4) dic = { "stevin" : "male"} se = { 1,2,3,4} with open("a.txt", "at",encoding="utf-8") as f : print(f.__iter__()) print(str.__iter__()) print(lis.__iter__()) print(tup.__iter__()) print(dic.__iter__()) print(se.__iter__())
迭代器(iterator):具有内置方法__iter__ 和__next__ . ps:迭代器一定是可迭代对象,可迭代对象不一定是迭代器对象。
同时具有内置方法__iter__方法和内置方法__next__的可迭代对象,可以通过__iter__方法得到就是该对象的迭代器对象
迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身
迭代器的取值必须使用__next__
迭代器的特点:只能按照次序向后取值,不能后退。
迭代取值:
优点
1.不依赖于索引取值
2.内存中永远只占一份空间,不会导致内存溢出
缺点
1.不能够获取指定的元素
2.取完之后会报StopIteration错
异常处理:当迭代器中的值被取完后,再用__next__取值会报出StopIteration异常
解决方法: try : 报错语句
except StopIteration : 捕获异常后的操作
l = [1,2,3,4] l = l.__iter__() while True : try: print(l.__next__()) except StopIteration : break
二.for循环的本质
for循环内部的本质
1.将in后面的literable对象调用__iter__转换成迭代器对象
2.调用__next__迭代取值
3.内部有异常捕获StopIteration,当__next__执行报错时,自动结束循环
三.生成器
生成器:个人自定义的迭代器,生成器的本质就是迭代器(具有__iter__ 和__next__两个内置方法)
生成器的定义与函数的定义类似,使用yield代替return来进行返回结果。
def func() : print("first") yield 111 #yield后面跟的是调用迭代器__next__方法返回的值 print("second") yield 222,"aaaa","bbbb" print("third") yield 333 print("fourth") yield 444 res = func() # 有yield函数名加(),不会让函数运行 # 而是生成器初始化,把函数变为迭代器对象。 print(res.__next__()) #返回一个值 print(res.__next__()) #以元祖的形式返回多个值 print(res.__next__())
yield外界传参
def dog (name) : print("%s 准备开吃" %name) while True: food = yield print('%s 吃了 %s' % (name, food)) g = dog('stevin') g.__next__() # 必须在运行代码yield时,才能进行传值 g.send('大骨头') # 给yield左边的变量传参 触发了__next__方法 g.send('饺子') g.send('饺子')
生成器表达式:
格式:(变量名 for 变量名 in 容器类型 if 判断条件)
with open("b.txt", "rt",encoding="utf-8") as f : res = (len(line) for line in f) # 生成器表达式 print(sum(res))
生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行
yield
1.帮你提供了一种自定义生成器方式
2.会帮你将函数的运行状态暂停住
3.可以返回值
yield与return的异同点
相同点:都可以返回值,并且都可以返回多个
不同点:
yield可以返回多次值,而return只能返回一次函数立即结束
yield还可以接受外部传入的值
四.内置方法
print(abs(-13.24)) # abs 求绝对值 l = [1,1,0] print(all(l)) # all 存在一个为False就返回False print(any(l)) # any 任意一位为True就返回True def index(): username = '我是局部名称空间里面的username' print(locals()) # locals 返回当前所在区域存储的所有的名字 print(globals()) # globals 无论在哪 返回的都是全局名称空间 index() print(bin(10)) # bin 十进制转2进制 print(oct(10)) # oct 十进制转8进制 print(hex(10)) # hex 十进制转16进制 print(int('0b1010',2)) # 其他进制转十进制 print(bool(1)) print(bool(0)) # bool判断真假 s = 'hello你好' print(s.encode('utf-8')) # encode 编码 print(bytes(s,encoding='utf-8')) # 字节流 def index(): pass print(callable(index)) # callable 可调用的(可以加括号执行相应功能的) print(chr(65)) # chr 将数字转换成ascii码表对应的字符 print(ord('A')) # ord 将字符按照ascii表转成对应的数字 print(dir(range(12))) # dir 获取当前对象名称空间里面的名字 print(divmod(101,10)) total_num,more = divmod(900,11) if more: total_num += 1 print('总页数:',total_num)# divmod 分页器 l = ['a','b','c','d'] for i,j in enumerate(l,1):# enumerate 枚举 print(i,j) # eval exec 执行字符串表达式 s1 = """ print(1 + 2) for i in range(10): print(i) """ # eval(s1) exec(s1) name = 'jason' s2 = """ name """ print(eval(s2)) # eval不支持逻辑代码,只支持一些简单的python代码 def login(): """ 一起嗨皮 :return: """ print(help(login)) # help 查看函数注释 print(isinstance("123",list)) # isinstance 判断对象是否属于某个数据类型 print(pow(2,3)) # 返回 x的y次方。 print(round(3.4)) # round 四舍五入,取整
五.面向过程编程
面向过程编程:类似与流程化设计
好处:
将复杂的问题简单化,流程化
坏处:
可扩展性较差 一旦需要修改 整体都会受到影响
六.面试题
def multipliers(): return [lambda x : i*x for i in range(4)] print([m(2) for m in multipliers()]) # 扩展版 def multipliers2(): list1 = [] for i in range(4): def func(x): #应该这么修改:def func(x, i=i): return x * i list1.append(func) return list1 print([m(2) for m in multipliers2()])