python学习:迭代器
一、可迭代对象
1、已经学过的可迭代对象:
str、list、tuple、dic、set、range、enumeraer、文件句柄 等都是可迭代对象。
2、在python中,只要内部方法中含有__iter__方法的对象,这个对象就是一个可迭代对象。
1 o1 = 'alex' 2 o2 = [1, 2, 3] 3 o3 = (1, 2, 3) 4 o4 = {'name': '太白','age': 18} 5 o5 = {1, 2, 3} 6 o6 = range(5) 7 o7 = enumerate(o2) 8 f = open('file',encoding='utf-8', mode='w') 9 print('__iter__' in dir(o1)) # True 10 print('__iter__' in dir(o2)) # True 11 print('__iter__' in dir(o3)) # True 12 print('__iter__' in dir(o4)) # True 13 print('__iter__' in dir(o5)) # True 14 print('__iter__' in dir(o6)) # True 15 print('__iter__' in dir(o7)) # True 16 print('__iter__' in dir(f)) # True
二、迭代器
1、同时含有__iter__方法和__next__方法的可迭代对象就是一个迭代器
1 o1 = 'alex' 2 o2 = [1, 2, 3] 3 o3 = (1, 2, 3) 4 o4 = {'name': '太白','age': 18} 5 o5 = {1, 2, 3} 6 o6 = range(5) 7 o7 = enumerate(o2) 8 f = open('file',encoding='utf-8', mode='w') 9 print('__iter__' in dir(o1)) # True 10 print('__iter__' in dir(o2)) # True 11 print('__iter__' in dir(o3)) # True 12 print('__iter__' in dir(o4)) # True 13 print('__iter__' in dir(o5)) # True 14 print('__iter__' in dir(o6)) # True 15 print('__iter__' in dir(o7)) # True 16 print('__iter__' in dir(f)) # True 17 print("=======分割线========") 18 print('__next__' in dir(o1)) # False 19 print('__next__' in dir(o2)) # False 20 print('__next__' in dir(o3)) # False 21 print('__next__' in dir(o4)) # False 22 print('__next__' in dir(o5)) # False 23 print('__next__' in dir(o6)) # False 24 print('__next__' in dir(o7)) # True 25 print('__next__' in dir(f)) # True 26 f.close()
虽然str、list、tuple、dic、set、range、enumeraer、文件句柄都是可迭代对象,但是上述结果显示只有enumeraer、文件句柄是迭代器。
2、可迭代对象可以使用__iter__()转换成迭代器。例如:
1 o3 = (1, 2, 3) 2 iter1 = o3.__iter__() 3 print('__iter__' in dir(iter1)) # True 4 print('__next__' in dir(iter1)) # True 5 6 o4 = {'name': '太白','age': 18} 7 iter2 = o4.__iter__() 8 print('__iter__' in dir(iter2)) # True 9 print('__next__' in dir(iter2)) # True
3、迭代器取值
迭代器使用__next__()方法取值,一个__next__取一个值,不能多取,如果取多了会抛出StopIteration的异常。
4、for循环的内部机制
for循环的对象一定是可迭代对象,for循环的内部自动将可迭代对象转换成了迭代器,然后用__next__来取值。
模拟for循环取值:
l1 = [1, 2, 3, 4, 5, 6] # 1 将可迭代对象转化成迭代器 obj = iter(l1) # 2,利用while循环,next进行取值 while 1: # 3,利用异常处理终止循环 try: print(next(obj)) except StopIteration: break
5、迭代器的优点
一个一个的取值,节约内存,在使用next取值的时候才生成一个值。
三、可迭代对象和迭代器的区别
可迭代对象:可迭代对象占用内存,不能直接循环取值(列表,字符串之所以能用for循环取值,是因为for循环内部自动将列表转换成迭代器)。但是如果需要快速处理数据,在内存足够大的情况下,还是可以使用可迭代对象更方便。
迭代器:节约内存,节约直接循环使用next取值。在大数据量的情况下,不用将所有数据全部放入内存,避免内存崩溃。那怎么把数据在需要的时候取出一部分呢,这就是生成器才能做的事情了。