迭代器和生成器
一.迭代器
1.1可迭代对象
1.1.1可迭代对象定义
-
在python中,但凡内部含有iter方法的对象,都是可迭代对象
1.1.2查看对象内部方法
-
该对象内部含有什么方法除了看源码还有什么其他的解决方式么?当然有了, 可以通过dir() 去判断一个对象具有什么方法
s1 = '张三' print(dir(s1)) #结果 ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
1.2迭代器
1.2.1迭代器的定义
-
我们简单来说:在python中,内部含有'Iter'方法并且含有'next'方法的对象就是迭代器。
1.2.2如何判断该对象是否是迭代器
-
示例:请判断这些对象:str list tuple dict set range 文件句柄 哪个是迭代器,哪个是可迭代对象:
n1 = '张三' n2 = [1, 2, 3] n3 = (1, 2, 3) n4 = {'name': '李四','age': 18} n5 = {1, 2, 3} f = open('file',encoding='utf-8', mode='w') print('__iter__' in dir(n1)) # True print('__iter__' in dir(n2)) # True print('__iter__' in dir(n3)) # True print('__iter__' in dir(n4)) # True print('__iter__' in dir(n5)) # True print('__iter__' in dir(f)) # True # hsagn print('__next__' in dir(n1)) # False print('__next__' in dir(n2)) # False print('__next__' in dir(n3)) # False print('__next__' in dir(n4)) # False print('__next__' in dir(n5)) # False print('__next__' in dir(f)) # True f.close()
所以只有文件句柄是迭代器,剩下的那些数据类型都是可迭代对象。
1.2.3可迭代对象如何转化成迭代器
a1 = [1, 2, 3, 4, 5, 6] obj = a1.__iter__() print(obj) #<list_iterator object at 0x00000000025A8A20> obj2 = iter(a1) print(obj2) #<list_iterator object at 0x0000000002528D30>
1.2.4迭代器取值
a1 = [1, 2, 3] obj = a1.__iter__() ret = obj.__next__() print(ret) # 1 ret = obj.__next__() print(ret) # 2 ret = obj.__next__() print(ret) # 3 ret = obj.__next__() print(ret) # StopIteration
# 迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,
# 那么就报StopIteration的错误。
二.生成器
2.1生成器函数
-
和普通函数没有区别,里面有yield的函数就是生成器函数
-
生成器函数在执行的时候,默认不会执行函数体,返回生成器
-
通过生成器的next()分段执行这个函数
-
send()给上一个yield传值,不能在开头(没有上一个yield),最后一个yield也不能用send()
def func(): print("abc") yield 1 print("def") yield 2 n1 = func() print(n1.__next__()) print(n1.__next__())
return 和yield都可以返回数据,n1 = func()不会执行函数,拿到的是生成器,执行生成器需要用next()
函数中如果有yield,这个函数就是生成器函数,生成器函数获取的是生成器
yield:相当于return,可以返回数据,但是yield不会彻底中断函数,而是分段执行函数
def func(): yield 1 yield 2 yield 3 print(list(func())) #内部有__next__() for i in func():#for的内部一定有__next__() print(i)
2.2生成器
-
生成器的本质就是迭代器
-
生成器的特点和迭代器一样,取值方式和迭代器一样(next())