一、什么是迭代器?
拥有__iter__方法和__next__方法的对象就是迭代器
1、迭代
迭代是访问集合元素的一种方式,可以将某个数据集内的数据“一个挨着一个的取出来”,就叫做迭代。
2、可迭代协议
协议就是互相规定好的。可迭代协议的定义非常简单,就是内部实现了__iter__方法。
3、迭代器协议:必须拥有__iter__方法和__next__方法。
练习:
(1)、列举 能被for 循环的内容
list、dic、str、set、tuple、f.open()、range()、enumerate
(2)、dir()方法获取对应数据类型的所有方法。
dir() 获取对应数据类型的所有方法,带有下划线的方法叫双下方法。
例如:print(dir([]))
(3)、查看 [],{},’’,range() 共有的方法:使用集合的交集进行获取。
找到了__iter__ 方法。有此方法的对象就是一个可以被迭代的对象
dir()方法获取对应数据类型的所有方法。
# print(dir([])) # 获取列表的所有方法
# print(dir(())) # 获取元组的所有方法
# print(set(dir([])) & set(dir(()))) #查看列表和元组的共有方法,取列表和元组的交集
# print([].__iter__()) #列表执行__iter__()方法之后,返回值就是一个迭代器
# print(dir([].__iter__())) # 打印其所有方法时,变成迭代器之后的方法比列表之前的方法少了
print(['a','b','c'].__iter__()) # 该列表执行__iter__()后返回值是一个迭代器
g=['a','b','c'].__iter__() # 给该迭代器赋值一个变量,就是获取迭代器
ret=g.__next__() # 使用__next__()方法获取'a'元素
print(ret)
ret2=g.__next__() # 使用__next__()方法获取'b'元素
print(ret2)
ret3=g.__next__() # 使用__next__()方法获取'c'元素
print(ret3)
运行结果:
<list_iterator object at 0x0000000001E8D240>
a
b
c
使用for循环:
lst=['a','b','c']
for i in lst:
print(i)
运行结果:
a
b
c
for循环原理:先判断lst是否可迭代,调用__iter__(),返回迭代器,调用迭代器的__next__()方法返回值给i
二、for循环原理
1.for循环一个可迭代的对象(实现__iter__方法)
2.__iter__方法返回一个迭代器(迭代器实现了__iter__方法和__next__方法)
3.for先判断对象地方可迭代,然后调用迭代器的__next__方法获取值。
三、.迭代器作用
节约内存,取得时候在生成数据,python2.7的时候range()方法就立刻生成了数据
占用了大量的内存空间。
四、.应用场景
1、数据类型转换 例如 list和元组之间的转换底层就是使用的迭代器
迭代器简单举例:
class Names(object):
def __init__(self):
self.lst = [] #使用列表保存信息
def add_name(self, name):
self.lst.append(name)
def __iter__(self):
return NamesIterator(self.lst)
class NamesIterator(object):
def __init__(self, lst):
self.lst = lst
self.current_num = 0
def __iter__(self):
pass
def __next__(self):
if self.current_num < len(self.lst):
name = self.lst[self.current_num]
self.current_num += 1
return name
else:
raise StopIteration # 异常抛给python内部
names = Names()
names.add_name('zs')
names.add_name('ls')
names.add_name('ww')
for name in names:
print(name)
运行结果:
zs
ls
ww
练习:使用迭代器生成斐波那契数列
class Fibonacci(object):
def __init__(self,all_num):
self.all_num=all_num
self.a=1
self.b=1
self.current_num=0
def __iter__(self):
return self # 返回自己,调用自己的魔术方法
def __next__(self):
if self.all_num<=2:
self.current_num+=1
if self.current_num==3:
raise StopIteration
return self.a
else:
if self.current_num<self.all_num:
ret=self.a # 1,1
self.a,self.b=self.b,self.a+self.b
# a=1,b=2
# a=2,b=3
self.current_num+=1
return ret
else:
raise StopIteration
feibonaqi=Fibonacci(3)
for i in Fibonacci(3):
print(i)
运行结果;
1
1
2