print(dir([])) #显示列表拥有的所有方法
1 print(dir([])) #显示列表拥有的所有方法 2 3 4 5 #结果如下: 6 ['__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']
l = [1,2,3,4,5] print(l.__iter__()) #结果 <list_iterator object at 0x109896518>
执行了list([1,2])的__iter__方法,得到了一个list_iterator,现在又得到了一个新名词——iterator
iterator,这里给我们标出来了,是一个计算机中的专属名词,叫做迭代器。
''' dir([1,2].__iter__())是列表迭代器中实现的所有方法,dir([1,2])是列表中实现的所有方法,都是以列表的形式返回给我们的,为了看的更清楚,我们分别把他们转换成集合, 然后取差集。 ''' #print(dir([1,2].__iter__())) #print(dir([1,2])) print(set(dir([1,2].__iter__()))-set(dir([1,2]))) 结果: {'__length_hint__', '__next__', '__setstate__'}
我们看到在列表迭代器中多了三个方法,那么这三个方法都分别什么用途呢?
iter_l = [1,2,3,4,5,6].__iter__() #获取迭代器中元素的长度 print(iter_l.__length_hint__()) #根据索引值指定从哪里开始迭代 print('*',iter_l.__setstate__(4)) #一个一个的取值 print('**',iter_l.__next__()) print('***',iter_l.__next__())
__next__能让我们一个一个取值
在for循环中,就是在内部调用了__next__方法才能取到一个一个的值。
那接下来我们就用迭代器的next方法来写一个不依赖for的遍历。
l = [1,2,3,4] l_iter = l.__iter__() item = l_iter.__next__() print(item) item = l_iter.__next__() print(item) item = l_iter.__next__() print(item) item = l_iter.__next__() print(item) item = l_iter.__next__() print(item)
但是这段代码在最后报错了,因为我们一直取next取到迭代器里已经没有元素了,就会抛出一个异常StopIteration,告诉我们,列表中已经没有有效的元素了。
接下来稍作修改,把这个异常报错处理掉:
l = [1,2,3,4] l_iter = l.__iter__() while True: try: item = l_iter.__next__() print(item) except StopIteration: break
现在我们就使用while循环实现了原本for循环做的事情,我们是从l_iter获取一个一个的值,这个l_iter就是一个迭代器。
Python中提供的生成器:
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
生成器Generator:
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
特点:惰性运算,开发者自定义
生成器函数
一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
def count(): yield 1 yield 2 yield 3 yield 4 yield 5 yield 6 yield 7 yield 8 g = count() print(g) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) #结果: <generator object count at 0x10c30ebf8> 1 2 3 4 5 6 7 8
生成器的应用实例:
def tail(filename): f = open(filename,encoding = 'utf-8') while True: line = f.readline() if line.strip(): yield line.strip() g = tail('file') for i in g: if 'python' in i: print('***',i)
生成器函数进阶: