Day 13 迭代器,生成器,内置函数
1.迭代器
- 可迭代对象:内部还有__iter__方法的对象叫做可迭代对象
- 迭代器对象:内部既有__iter__方法,又含有__next__方法的对象叫做迭代器对象
- 迭代器一定是可迭代对象,可迭代对象不一定是迭代器对象
- 可迭代对象常用数据类型(list,tuple,str,set,dict,文件句柄) 文件句柄属于迭代器对象
- 可迭代对象使用__iter__(iter())方法可以生成一个迭代器
list1 = [1, 2, 3, 4, 5, 6] print(list1.__iter__()) # <list_iterator object at 0x000002A6FECB71D0> 返回一个迭代器对象
list1 = [1, 2, 3, 4, 5, 6] l = iter(list1) print(l) # <list_iterator object at 0x0000025809147390> l1 = iter(l) # 迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身 print(l1) # <list_iterator object at 0x0000025809147390>
- 迭代器通过__next__方法一个一个元素取值,当取完里面所有元素后,继续取值会触发StopIteration异常,next方法只能向后依次取值,不可逆
list1 = [1, 2, 3, 4, 5, ] l = iter(list1) print(l.__next__()) # 1 print(l.__next__()) # 2 print(l.__next__()) # 3 print(l.__next__()) # 4 print(l.__next__()) # 5 print(l.__next__()) # StopInteration
- __next__方法取值的优点是不依赖索引取值,内存中只有一份内存空间不会导致内存溢出,缺点是不能获取指定的元素,取值完以后会触发StopIteration异常
- for 循环的本质 1:将in后的对象调用iter()方法得到一个迭代器 2 通过next 方法取值 3 捕获StopIteration异常,当报错自动终止循环
list1 = [1, 2, 3, 4, 5, 6] iter_list = iter(list1) while 1: try: print(iter_list.__next__()) except StopIteration: break
2.生成器:本质就是迭代器,只不过是用户自定义的迭代器
- yield 关键字:yield后面跟的值就是调用迭代器__next__方法能得到的值,yield既可以返回一个值也可以返回多个值,返回多个值的时候以元组的方式返回,函数内部如果有yield关键字,那么加括号调用函数时并不会触发函数内部函数体的运行,而是得到一个生成器
# 自写range()函数 def my_range(x,y,z=1): while x < y: yield x x += z for i in my_range(1,10,2): print(i,end=' ') # 1 3 5 7 9
- yield 传参:
def sport(name): print(f'{name}开始运动') while 1: game = yield print(f'{name}开始{game}') g = sport('小明') # 当函数内有yield关键字的时候,调用该函数不会执行函数体代码,而是将函数变成生成器 g.__next__() # 小明开始运动 必须先将代码运行至yield 才能够为其传值 g.send('踢足球') # 为函数中game传值并调用 __next__()方法 小明开始踢足球 g.send('跑步') # 小明开始跑步
- yield 与 return 的异同点 相同点: 都可以返回值 不同点 yield可以返回多次值,而return返回值后直接结束函数, yield还可以传参
- yield面试题分解:
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())) res=list(g) # 基于for 循环.此时执行所有的生成器内部的代码 print(res) # [20, 21, 22, 23] """ for i in (add(10,i) for i in test()): 会执行所有的生成器内部的代码 add(n,i) """
3.内置函数
- abs() 绝对值
print(abs(-5)) # 5 print(abs(5)) # 5
- all() , any() 判断一个可迭代对象是否有bool值为False的元素
l = ['', 'a', 'b'] print(all(l)) # False 只要有一个为False就返回False print(any(l)) # True 只要有一个为True 就返回True
- bin(),oct(),hex()
print(bin(10)) # 0b1010 10转2 print(oct(10)) # 0o12 10转8 print(hex(10)) # 0xa 10转16
- bytes()
s = 'hello' print(bytes(s,encoding='utf-8')) # b'hello' 将字符串转化为bytes类型
- callable() 判断对象是否可调用
s = 'hello' def func(): pass print(callable(s)) # False print(callable(func)) # True
- chr() ord()
print(chr(97)) # 将数字转换成ascii码表对应的字符 print(ord('a')) # 将字符按照ascii表转成对应的数字
- dir() 获取当前对象名称空间里面的名字
l = [1, 2, 3, 4, 5] print(dir(l)) ''' ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] '''
- divmod() 求商数余数
a, b = divmod(100,9) print(a,b) # 商为11,余1
- enumerate() 枚举
l = ['a', 'b', 'c', 'd'] for index,i in enumerate(l): print(index,i,end=' ') # 0 a 1 b 2 c 3 d
- eval() 将字符串当作代码来执行,支持简单的,不支持逻辑运算,不支持赋值运算
s = 'print(1 + 2)' eval(s) # 3
- exct() 将字符串当作代码来执行
s = ''' for i in range(5): print(i,end=" ") ''' exec(s) # 0 1 2 3 4
- globals():查看全局命名空间里的名字:
print(globals()) # '__name__': '__main__', '__doc__': None, '__package__'.... def func(): name = 'xiaoming' print(globals()) # '__name__': '__main__', '__doc__': None, '__package__'..... # 无论在哪里都查看的是全局名称空间里的名字 func()
- locals():查看所在命名空间里的名字
print(locals()) # {'__name__': '__main__', '__doc__': None, '__package__': None... def func(): name = 'xiaoming' print(locals()) # {'name': 'xiaoming'} func()
- isinstans() 判断对象是否属于某个数据类型
a = 1 print(isinstance(a,int)) # True 判断变量a是否是int类型
- sum() 求和:
print(sum([2,4,5,6])) # 17
- round() 对浮点数进行四舍五入处理
print(round(5.4)) # 5 print(round(5.5)) # 6
- pow 幂运算
print(pow(2,3)) # 2**3 8