0.什么是迭代器(iterator)与迭代对象?
比如:python中的集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等,我们可以使用for遍历其中的每个元素,此外生成器也可以被for遍历。如下:这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。
str = "abcedff"
ls = [2,343,'ab',[1,2,"aa"]]
dic = {1:"tom","python":"cool",1:3}
for i in str:
print(i)
for j in ls:
print(j)
for k,v in dic.items() :
print(k,v)
1.可以使用 isinstance() 判断一个对象是否是 Iterable 对象:即是否可以被for循环进行遍历元素
#1.判断一个对象是否是可迭代类型,对象能够使用迭代的前提是可迭代类型
from collections import Iterable
str = "abcedff"
ls = [2,343,'ab',[1,2,"aa"]]
dic = {1:"tom","python":"cool",1:3}
print(isinstance(str,Iterable))
print(isinstance(ls,Iterable)) #True
print(isinstance(dic,Iterable))#True
2.使用__iter__方法创建可迭代对象,注意不是迭代器
from collections import Iterable,Iterator
class MyList(object):
def __init__(self):
self.container = []
def add(self, item):
self.container.append(item)
def __iter__(self): #__iter__方法是使一个非迭代器转换迭代器。
pass # 先忽略如何构造一个迭代器对象
mylist = MyList()
print(isinstance(mylist, Iterable)) #True
print(isinstance(mylist, Iterator)) #Fasle
注意:迭代对象,Iterable对象并不一定能够进行迭代。什么是迭代器呢?可以被next()函数调用并不断返回下一个值的对象称为迭代器Iterator。迭代是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
3..可以使用 isinstance() 判断一个对象是否是 Iterator 对象,只有一个对象是迭代器对象才可以被迭代。
from collections import Iterable
from collections import Iterator
str = "abcedff"
ls = [2,343,'ab',[1,2,"aa"]]
dic = {1:"tom","python":"cool",1:3}
print(isinstance(str,Iterable)) #True,是迭代对象,可以被for遍历
print(isinstance(str,Iterator)) #False,但不是迭代器,不能够被next()函数调用
print(isinstance(ls,Iterable)) #True,是迭代对象,可以被for遍历
print(isinstance(ls,Iterator)) #False,但不是迭代器,不能够被next()函数调用
print(isinstance(dic,Iterable)) #True,是迭代对象,可以被for遍历
print(isinstance(dic,Iterator)) #False,但不是迭代器,不能够被next()函数调用
2.创建转换迭代器
迭代器有两个基本的方法:iter() 和 next()。生成器都是 Iterator 对象,但 list 、 dict 、 str 虽然是 Iterable ,却不是 Iterator 。把 list 、 dict 、 str 等 Iterable 变成 Iterator 可以使用 iter() 函数
1.使用iter()将迭代对象转换成迭代器
ls = ["aa",11,"bb",22]
print(isinstance(ls,Iterator)) #Fasle
ls =iter(ls) #将列表转换成Iterator
print(isinstance(ls,Iterator)) #True.
总结:list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的__iter__
方法。
2.迭代器不断使用next()函数来获取下一条数据
>>> li = [11, 22, 33, 44, 55]
>>> li_iter = iter(li)
>>> next(li_iter)
11
>>> next(li_iter)
22
>>> next(li_iter)
33
>>> next(li_iter)
44
>>> next(li_iter)
55
>>> next(li_iter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
通过上面的分析,我们已经知道,迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的__next__
方法(Python3中是对象的__next__
方法,Python2中是对象的next()方法)。
所以,我们要想构造一个迭代器,就要实现它的__next__
方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__
方法,而__iter__
方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__
方法返回自身即可。
3.一个实现了__iter__
方法和__next__
方法的对象,就是迭代器
from collections import Iterator,Iterable
class MyList(object):
"""自定义的一个可迭代对象"""
def __init__(self):
self.items = []
def add(self, val):
self.items.append(val)
def __iter__(self):
myiterator = MyIterator(self)
return myiterator
class MyIterator(object):
"""自定义的供上面可迭代对象使用的一个迭代器"""
def __init__(self, mylist):
self.mylist = mylist
# current用来记录当前访问到的位置
self.current = 0
def __next__(self):
if self.current < len(self.mylist.items):
item = self.mylist.items[self.current]
self.current += 1
return item
else:
raise StopIteration
def __iter__(self):
return self
if __name__ == '__main__':
mylist = MyList()
mylist.add(1)
mylist.add(2)
mylist.add(3)
mylist.add(4)
mylist.add(5)
for num in mylist:
print(num)
print(isinstance(MyIterator(mylist),Iterator)) #True
print(isinstance(mylist, Iterable)) #True
'''
1
2
3
4
5
'''
3.迭代器的遍历for和next()使用
使用for循环,这也是最常用的,但是注意对生成器函数使用for无法获取函数返回值,这时候可以用next()代替,或者使用对象自带__next__()方法也可。
for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
1.对普通迭代器使用for进行遍历内容
ls = ["aa",11,"bb",22]
ls =iter(ls)
for i in ls :
print(i,end=" ") #aa 11 bb 22 2
g = (x for x in range(2,10))
for j in g:
print(j,end=",")#2,3,4,5,6,7,8,9,
2.对函数生成器使用for进行遍历,要注意。
def fc(agrs):#打印1到args的圆的面积
PI= 3.14
i = 1
while i <agrs:
yield PI*i**2
i +=1
return "game over!"
1.使用for如果迭代的是函数生成器,那么无法获取返回值
for i in fc(8) :
print(i,end=",") #3.14,12.56,28.26,50.24,78.5,113.04,153.86,
2如果想获取函数生成器的返回值,要用next()方法
f = fc(8)
while True:
try:
area = next(f) #注意这里不能直接写next(fc(8)),会形成死循环。
print(area,end=",")
except StopIteration as e:
print("返回值就在异常的值里,是:%s"%e.value)
break #一定要加break,或者循环终止不了。
'''结果如下:
3.14,12.56,28.26,50.24,78.5,113.04,153.86,返回值就在异常的值里,是:game over!
'''
3.如果想获取函数生成器的返回值,还可以使用__next__()方法
f = fc(8)
while True:
try:
area = f.__next__() #效果跟next(f)没有什么区别。
print(area,end=",")
except StopIteration as e:
print("返回值就在异常的值里,是:%s"%e.value)
break #一定要加break,或者循环终止不了。
'''结果如下:
3.14,12.56,28.26,50.24,78.5,113.04,153.86,返回值就在异常的值里,是:game over!
'''
统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。