可迭代对象:内部含有__inter__的python
可迭代对象不能取值,由于内部没有__next__()方法app
可迭代对象------>迭代器:ssh
boj.__iter__()或者inter(obj)ide
实现的原理相似于往弹匣里面装子弹,而后一个一个往外发射函数
经过__iter__()来获取到迭代器spa
1 stes = {1, 2, 3, 4, 5, 67, 7} 2 print(stes.__dir__()) 3 s = stes.__iter__() 4 print(s)
打印结果code
1 ['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__sub__', '__rsub__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__isub__', '__iand__', '__ixor__', '__ior__', '__len__', '__contains__', '__new__', 'add', 'clear', 'copy', 'discard', 'difference', 'difference_update', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', '__reduce__', 'remove', '__sizeof__', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__'] 2 <set_iterator object at 0x0000000001EF1480>
经过__next__()来拿到元素,一次只能拿一个,若是最后一个元素以后继续使用__next__(),会报错:StopIterationorm
1 stes = {1, 2, 3, 4, 5, 67, 7} 2 s = stes.__iter__() 3 print(s.__next__()) 4 print(s.__next__()) 5 print(s.__next__()) 6 print(s.__next__()) 7 print(s.__next__()) 8 print(s.__next__()) 9 print(s.__next__()) 10 print(s.__next__())
打印结果为:对象
1 1 2 2 3 3 4 4 5 5 6 67 7 7 8 Traceback (most recent call last): 9 File "C:/Python/Module/regex_test.py", line 53, in <module> 10 print(s.__next__()) 11 StopIteration
判断是否为迭代器:blog
1.经过__iter__(),__next__()是否在obj.__dir__()
1 with open('01','w', encoding='utf-8') as f: 2 print('__iter__' in dir(f)) 3 print('__next__' in dir(f)) 4 """ 5 打印结果: 6 True 7 True 8 说明文件句柄自己是一个迭代器 9 """
2.经过collections模块中的Iterable来判断
1 from collections import Iterable 2 from collections import Iterator 3 4 l = [1,2,3,4] 5 print(isinstance(l, Iterable)) # 判断是否为可迭代对象 6 print(isinstance(l, list)) 7 8 9 """ 10 打印结果: 11 True 12 True 13 """ 14 15 l = [1,2,3,4] 16 print(isinstance(l, Iterable)) 17 print(isinstance(l, Iterator)) 18 print(isinstance(l, list)) 19 20 """ 21 打印结果: 22 True 23 False 24 True 25 """
生成器实质就是迭代器,在python中有三种方式来获取生成器:
1. 经过生成器函数
2. 经过各类推导式来实现来生成器
3. 经过数据的转换也能够获取生成器
生成器是咱们本身用Python代码写的迭代器:
1 def gener(): 2 print(111) 3 yield 222 4 print(333) 5 yield 444 6 print(555) 7 yield 666 8 print(777) 9 yield 888 10 11 12 gen = gener() 13 print(gen) 14 15 # 打印结果为:<generator object gener at 0x0000000001E74D00>
生成器函数和普通的函数的区别就是把return换成了yield
yield 和return区别
1. 若是函数中包含了yield, 这个函数是一个生成器函数. 执行函数的时候是: 生成器
2. 生成器执行__next__(). 执行到下一个yield
3. yield的做用和return基本相同. 可是,只负责返回. 不会结束函数
4. return,结束函数.
经过obj__next__()方法取值:
1 def gener(): 2 print(111) 3 yield 222 4 print(333) 5 yield 444 6 print(555) 7 yield 666 8 print(777) 9 yield 888 10 11 12 gen = gener() 13 print(gen) 14 ret = gen.__next__() # 这里的ret至关于执行函数,直行道yield是返回yield的返回值 15 print(ret) 16 ret1 = gen.__next__() 17 print(ret1) 18 ret2 = gen.__next__() 19 print(ret2) 20 ret3 = gen.__next__() 21 print(ret3) 22 23 """ 24 打印结果: 25 <generator object gener at 0x0000000000814D00> 26 111 27 222 28 333 29 444 30 555 31 666 32 777 33 888 34 """
生成器还能够经过send()方法进行取值个传值,不过使用send方法时要注意的是:
1.第一个yield必须经过__next__()方法取得
2.最后一个yield不能经过send()方法传值.
1 def gener(): 2 print(111) 3 a = yield 222 4 print(a) 5 print(333) 6 b = yield 444 7 print(b) 8 print(555) 9 c = yield 666 10 print(c) 11 print(777) 12 yield 888 13 14 15 gen = gener() 16 print(gen) 17 ret = gen.__next__() 18 print(ret) 19 ret1 = gen.send('<<>>') 20 print(ret1) 21 ret2 = gen.send('<<>>') 22 print(ret2) 23 ret3 = gen.send('<<>>') 24 print(ret3) 25 26 """ 27 打印结果: 28 <generator object gener at 0x0000000001DD4D00> 29 111 30 222 31 <<>> 32 333 33 444 34 <<>> 35 555 36 666 37 <<>> 38 777 39 888 40 """
使用send()方法时要注意的是要传参,否则会报错
send和__next__() 区别:
send能够给上一个yield 的位置传递值 , 第一个必须用__next__()
__next__() 不能传值
须要一个列表,里面包含1到13的数字,第一反应是:
1 l = [] 2 3 for i in range(1, 14): 4 l.append(i) 5 print(l) 6 # 打印结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
咱们来看这样一段代码:
1 l = [ i for i in range(1,14)] 2 print(l) 3 4 #打印结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
有这样一个需求,经过列表推导式来筛选憨厚两个e的名字:
1 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], 2 ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] 3 name2 = [name for i in names for name in i if name.count('e') == 2] 4 print(name2) 5 6 # 打印结果:['Jefferson', 'Wesley', 'Steven', 'Jennifer']
l = [变量(加工后的变量) for 变量 in iterable] 循环模式
l = [变量(加工后的变量) for 变量 in iterable if 条件] 筛选模式
相似于真样的式子被成为列表推导式.
优势:
1,节省代码,一行搞定.
2,看着高大上.
缺点:
很差排错.
总体:
凡是用列表推导式构造的列表对象,用其余方式均可构建.,很是复杂的列表,列表推导式是构建不出的,
列表推导式比较有魔性.
生成器表达式和列表推导式基本同样,惟一的区别就是把列表推推导式的方括号变成圆括号:
1 l = ( i for i in range(1,14)) 2 print(l) 3 4 #打印结果:<generator object <genexpr> at 0x0000000001F24D00>
一样的也有两种模式:
循环模式和筛选模式