一、iterator即迭代器
可以被next()
函数调用并不断返回下一个值的对象称为迭代器,要创建一个iterator,必须实现一个有__iter__()和__next__()方法的类。
(1)可迭代对象(iterable),可用for in 语句遍历,比如列表(list),元组(tuple),集合(set) , 字典(dict) 等
(2)对象 class,一个类对象不能直接被for语句循环,可将一个类变为一个生成器,比如:
class BookClollection:
def __init__(self):
pass
#实现方法1
def __iter__(self):
pass
#实现方法2
def __next__(self):
pass
案例1:循环遍历类中的数据
class SkillClollection:
def __init__(self):
self.data = ['Q技能','W技能','E技能','R技能']
self.cur = 0
def __iter__(self):
return self
def __next__(self):
if self.cur >= len(self.data):
raise StopIteration()
r = self.data[self.cur]
self.cur +=1
return r
skills = SkillClollection()
for skill in skills:
print(skill)
结果:Q技能 W技能 E技能 R技能
案例2:使用迭代器的next()方法
class SkillClollection:
def __init__(self):
self.data = ['Q技能','W技能','E技能','R技能']
self.cur = 0
def __iter__(self):
return self
def __next__(self):
if self.cur >= len(self.data):
raise StopIteration()
r = self.data[self.cur]
self.cur +=1
return r
skills = SkillClollection()
print(next(skills))
print(next(skills))
print(next(skills))
结果:Q技能 W技能 E技能 R技能
迭代器的特性:一次性
案例3 :迭代器的一次性
class SkillClollection:
def __init__(self):
self.data = ['Q技能','W技能','E技能','R技能']
self.cur = 0
def __iter__(self):
return self
def __next__(self):
if self.cur >= len(self.data):
raise StopIteration()
r = self.data[self.cur]
self.cur +=1
return r
skills = SkillClollection()
for skill in skills:
print(skill)
for skill in skills:
print(skill)
结果:Q技能 W技能 E技能 R技能
结论:只打印一次(如果要打印多次可以创建多个对象)
如果要多次使用迭代器,除了案例3中创建对象的方法外,还可以使用浅拷贝或者深拷贝的方法:
案例4:使用浅拷贝的方法实现打印多次
import copy
class SkillClollection:
def __init__(self):
self.data = ['Q技能','W技能','E技能','R技能']
self.cur = 0
def __iter__(self):
return self
def __next__(self):
if self.cur >= len(self.data):
raise StopIteration()
r = self.data[self.cur]
self.cur +=1
return r
skills = SkillClollection()
skill_copy = copy.copy(skills)
for skill in skills:
print(skill)
for skill in skill_copy:
print(skill)
结果:
Q技能
W技能
E技能
R技能
Q技能
W技能
E技能
R技能
案例5:使用深拷贝的方法实现打印多次
import copy
class SkillClollection:
def __init__(self):
self.data = ['Q技能','W技能','E技能','R技能']
self.cur = 0
def __iter__(self):
return self
def __next__(self):
if self.cur >= len(self.data):
raise StopIteration()
r = self.data[self.cur]
self.cur +=1
return r
skills = SkillClollection()
skill_copy = copy.deepcopy(skills)
for skill in skills:
print(skill)
for skill in skill_copy:
print(skill)
二、generator即生成器,一个简单的创建iterator的途径,是一个能够返回迭代器对象的函数。
案例:打印0~100000
#普通方法,消耗内存影响性能,比如:
n = [i for i in range(0, 10000)]
print(n)
#迭代器方法
def gen(max):
n = 0
while n<=max:
n+=1
yield n
g = gen(10000)
print(next(g))
print(next(g))
print(next(g))
结果:1 2 3
原理:生成器内部没有保存数据,而是保存了算法
小提示:判断一个对象是否是Iterable
对象,可用isinstance()方法
比如:
from collections import Iterable
#判断列表
a = isinstance([],Iterable)
#判断集合
b = isinstance({},Iterable)
#判断字符串
c = isinstance('asd',Iterable)
#判断元组
d = isinstance((x for x in range(10)),Iterable)
#判断Number
e = isinstance(100,Iterable)
print(a,b,c,d,e)
结果:True True True True False