typhoonpython 2019-12-20
可迭代对象
什么是对象:
Python中,一切皆对象。一个变量,一个列表,一个字符串,文件句柄,函数等等都可称为一个对象。一个对象就是一个实例,就是实实在在的东西。
什么是迭代
迭代就是一个重复的过程,但还不是单纯的重复,就像是父亲,自己,儿子,孙子的关系,都是复制,但结果是不一样的。还有使用的APP,微信,抖音等隔一段时间就会基于上一次做一些更新,那么这就是迭代。
结论:
可迭代对象从字面意思就是一个可以重复取值的实施在在的东西。
不可迭代的有:
在Python中,有很多可迭代对象,那么就说说哪些不是:int,bool这两种类型不是可迭代的。
查看是否是可迭代对象:
在Python中,但凡内部含有iter方法的对象,都是可迭代对象。
除了直接看源码以外,可以使用dir()来判断源码内是否有iter方法。
dir()会将数据类型的方法以列表中含有字符串的形式进行输出。
s = 123 print(‘__iter__‘ in dir(s)) #False ? s1 = ‘123‘ print(‘__iter__‘ in dir(s1)) #True ? s2 = (1,2,3,4,5) print(‘__iter__‘ in dir(s2)) #True
可迭代对象的优缺点:
优点:可直观的查看里面的数据
缺点:占用内存,可迭代对象不能迭代取值。(除去索引,key以外)
其中可迭代对象不能迭代的问题,是可以通过for循环来取值的。但其实for循环在底层做了一个小小的转化,就是将迭代对象转换成迭代器,然后进行取值。
迭代器:
是一个可以迭代取值的工具。专业点就是看类型中有没有iter和next方法,有就是一个迭代器。
__iter__ and __next__
有哪些对象是可迭代器呢:
s1 = 123 s2 = ‘123‘ s3 = (1,2,3,4,5) s4 = [1,2,3,4] s5 = {1,2,3,4,5} s6 = {‘name‘:‘xuan‘,} f = open(‘test.txt‘) ? print(‘__iter__‘ in dir(s1)) #False print(‘__iter__‘ in dir(s2)) #True print(‘__iter__‘ in dir(s3)) #True print(‘__iter__‘ in dir(s4)) #True print(‘__iter__‘ in dir(s5)) #True print(‘__iter__‘ in dir(s6)) #True print(‘__iter__‘ in dir(f)) #True print(‘__next__‘ in dir(s1)) #False print(‘__next__‘ in dir(s2)) #False print(‘__next__‘ in dir(s3)) #False print(‘__next__‘ in dir(s4)) #False print(‘__next__‘ in dir(s5)) #False print(‘__next__‘ in dir(s6)) #False print(‘__next__‘ in dir(f)) #True
可以看到,只有文件句柄是迭代器。
可迭代对象转换成迭代器:
那么如何将可迭代对象转换成迭代器呢:
l1 = [1,2,3,4,5,6] obj1 = l1.__iter__() print(obj1) #或 obj2 = iter(l1) print(obj2)
可迭代对象取值:
可以使用iter来转换为迭代器,然后使用next来取值。当取值用完,任然要取的时候,就会报StopIteration的错误,
l1 = [1,2,3,4,5,6] obj1 = l1.__iter__() print(obj1.__next__()) print(obj1.__next__()) print(obj1.__next__()) print(obj1.__next__()) print(obj1.__next__()) print(obj1.__next__()) print(obj1.__next__()) print(obj1.__next__())
会了这个以后,我们就可以使用while来循环取值了。
l1 = [1,2,3,4,5,6] obj1 = l1.__iter__() while True: try: print(next(obj1)) except StopIteration: break
迭代器和可迭代对象的对比:
可迭代对象:
私有的方法比较多,像列表和字典中的增删改查。比较直观,但是占用内存,而且不能直接通过循环迭代取值。当你侧重于对数据可灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
迭代器:
是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。当你数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
总结:
字面上讲,迭代器就是迭代取值的工具。
从专业角度上讲,在Python中,内部含有iter方法并且含有next方法的对象就是迭代器了。
迭代器的优点:
节省内存:迭代器在内存当中相当于只占一个数据的空间,因为每一个取值,都会把上一条数据内存释放后再加载当前的此条数据。
惰性机制:next一次取一个值,绝不过多取值。
缺点:
不能直观的查看里面的数据
取值时不走回头路,智能一直向下取值。