迭代器

2018-11-04  本文已影响0人  w_wm_m

可迭代对象

     可以用for循环的都是可迭代对象,那么为什么有的对象可以用for循环,而有的确不行呢?

list
tuple
dict
set
range()
enumerate()
....

     这些对象都可以用for循环取得想要的值。

ls = dir(list)
tu = dir(tuple)
di = dir(dict)
se = dir(set)
ra = dir(range(10))
en = dir(enumerate([]))
#使用dir获得参数的属性,方法列表
s = set(ls) & set(tu) & set(di) & set(se) & set(ra) & set(en)
#取交集
print(s)

     在这些交集中有一个属性为__iter__。也正是因为这个属性,它们才可以被迭代,也就是用for循环。
     综上,当一个对象拥有__iter__方法时,它就是一个可迭代对象,也就可以用for循环。

迭代器

print(type([].__iter__()))
迭代器.png

     我们对列表使用一下__iter__()方法,查看它的类型发现它变成了iterator,也就是迭代器

print(dir([].__iter__()))
ls = [1,2,3]
iterator = ls.__iter__()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
迭代器.png

     在iterator的众多方法中有一个叫做__next__()的方法,使用它可以依次得到iterator中的值。
     同样它也有一个__iter__()方法,说明可以对iterator进行for循环

ls = [1,2,3]
iterator = ls.__iter__()
for i in iterator:
    print(i)

     当然我们也可以使用while

ls = [1,2,3]
iterator = ls.__iter__()
while True:
    print(iterator.__next__())
迭代器.png

     如果用while True将会一直取下一个元素,但如果没有下一个元素了怎么办,这时就会抛出一个StopIterator的异常,表示已经取到最后一个了,不能再往下继续了。

     现在来说说for的工作原理,如果给它的不是一个可迭代对象,它就直接报错,如果给它一个可迭代对象像list...它会先调用内置的__iter__()方法得到该对象的迭代器对象,然后调用迭代器对象的__next__()方法,一直依次向下取得迭代器对象中的每一个元素,直到迭代器没有下一个元素了。如果给它的直接是一个迭代器对象,那么就直接调用__next__()方法

Tips:

isinstance

     如果我们要判断一个对象是不是一个可迭代对象或者是一个迭代器对象的时候,我们去查看dir,一个一个找它们是不是有__iter__()或是__next__(),实在太low,这时候我们使用isinstance()函数即可判断。

from collections import Iterable,Iterator
print(isinstance([],Iterable))
print(isinstance([],Iterator))
print(isinstance({1,2,3},Iterable))
迭代器.png

xrange和range

     现在讨论这个问题可能已经没有多大意义了,因为在Python3.x中xrange和range被统一为range

上一篇下一篇

猜你喜欢

热点阅读