一、36_1迭代器
# (答辩题):
# 迭代器可以实现for循环,能够取出里边遍历的每一个数据
# 它里边存的不是生成序列的结果,而是生成序列的方式
# 占用空间特别小
for tempin [11,22,33]:
print(temp)
for tempin "abcdef":
print(temp)
# 数字类型不可以迭代
# for temp in 100:
# print(temp)
# iterable:可迭代
# 判断可否迭代的代码
from collectionsimport Iterable
print(isinstance("abc", Iterable))# True
print(isinstance(100, Iterable))# False
print(isinstance([11,22,33], Iterable))# True
print(isinstance((11,22,33), Iterable))# True
二、36_2自己实现一个可以迭代的对象
from collectionsimport Iterable
from collectionsimport Iterator
import time
"""
1、判断xxx_obj是否是可以迭代
看xxx_obj看对象的类中是否有_iter_方法
2、在第一步成立的前提下,调用iter函数,得到xxx_obj对象的_iter_方法的返回值
调用iter函数会自动调用_iter_方法
3、_iter_方法的返回值是一个迭代器_next_方法,调一次取一个赋给temp
for temp in xxx_obj:
pass
"""
class Classmate(object):
def __init__(self):
self.names =list()
self.current_num =0
def add(self, name):
self.names.append(name)
def __iter__(self):
"""如果想要一个对象成为一个可以迭代的对象(即可以使用for)
那么必须实现_iter_方法"""
# return ClassIterator(self)
return self
def __next__(self):
if self.current_num
ret =self.names[self.current_num]
self.current_num +=1
return ret
else:
raise StopIteration
# class ClassIterator(object):
# def _init_(self, obj):
# self.obj = obj
# self.current_num = 0
#
# def _iter_(self):
# pass
#
# def _next_(self):
# if self.current_num < len(self.current_num):
# ret = self.obj.names[self.current_num]
# self.current_num += 1
# return ret
# else:
# raise StopAsyncIteration
classmate = Classmate()
classmate.add("张三")
classmate.add("王二")
classmate.add("老王")
# print("判断classmate是否是可以迭代的对象:", isinstance(classmate, Iterable))
# classmate_iterator = iter(classmate)
# print("判断classmate_iterator是否是迭代器:", isinstance(classmate_iterator, Iterable))
# print(next(classmate_iterator))
for namein classmate:
print(name)
time.sleep(1)
三、37_斐波那契数列
"""
a = 0
b = 1
print(a)
a, b = b, a+b # (1, 0+1)
print(a)
a, b = b, a+b # (1, 0+1)
print(a)
a, b = b, a+b # (1, 0+1)
print(a)
"""
"""fibonaqi:斐波那契数列"""
"""方法一、"""
# nums = list()
# a = 0
# b = 1
#
# i = 0
# while i < 10:
# nums.append(a)
# a, b = b, a+b
# i += 1
#
# for num in nums:
# print(num)
"""方法二"""
class Fibonacci(object):
"""初始化"""
def __init__(self, all_num):
self.all_num = all_num
"""当前的索引"""
self.current_num =0
self.a =0
self.b =1
"""可迭代"""
def __iter__(self):
return self
"""迭代函数"""
def __next__(self):
if self.current_num
ret =self.a
self.a, self.b =self.b, self.a+self.b
self.current_num +=1
return ret
else:
raise StopIteration
fibo = Fibonacci(10)
for numin fibo:
print(num)
四、迭代器的其它作用
"""
9、并不是只有for循环能接收可迭代对象,除了for
循环能接收可迭代对象,list、tuple等也能接收
li = list(FibIterator(15))
print(li)
tp = tuple(FibIterator(6))
print(tp)
"""
a = (11,22,33)
"""把元组转为列表"""
"""重新生成一个新列表,把数据遍历迭代存入"""
print(list(a))#[11, 22, 33]
"""
1、重新生成一个空列表
2、调用里边的迭代器,a有一个迭代对象
3、list函数就找到了里边的迭代器
4、通过__next__方法取元组里的每一个值
5、每取到一个值,通过append方式,
* 放到那个新生成的空列表里
6、不能迭代会生成并抛出一个异常,
* 但list函数会自动处理异常
"""
五、39_生成器
"""生成器是一个特殊的迭代器"""
"""
创建生成器方法一、
*把一个列表生成式的[]改成()
"""
# nums = [x*2 for x in range(10)]
# print(nums)
#
# nums = (x*2 for x in range(10))
# print(nums)
#
# for num in nums:
# print(num)
"""
创建生成器方法二、
!!!如果一个函数里有yield语句
,那么这个函数就变为生成器的模板!!!
"""
"""使用生成器执行fibonaqi数列"""
def creatr_num(all_num):
print('---1---')
# a = 0
# b = 1
a, b =0, 1
"""当前索引"""
current_num =0
while current_num < all_num:
print('---2---')
# print(a)
yield a
print('---3---')
a, b = b, a+b
current_num +=1
print('---4---')
# creatr_num(10)
"""!!!函数里有yield,它的(调用函数)
,变为创建一个生成器的对象!!!"""
obj = creatr_num(10)
"""希望创建多个生成器的对象"""
obj2 = creatr_num(2)
# for num in obj:
# print(num)
ret =next(obj)
print("obj:", ret)
ret =next(obj)
print("obj:", ret)
ret =next(obj2)
print("!!!obj2!!!:", ret)
ret =next(obj)
print("obj:", ret)
ret =next(obj)
print("obj:", ret)
ret =next(obj)
print("obj:", ret)
ret =next(obj2)
print("!!!obj2!!!:", ret)
ret =next(obj2)
print("!!!obj2!!!:", ret)
六、40_1通过异常判断生成器已经结束
"""
创建生成器方法二、
!!!如果一个函数里有yield语句
,那么这个函数就变为生成器的模板!!!
"""
"""使用生成器执行fibonaqi数列"""
def creatr_num(all_num):
# a = 0
# b = 1
a, b =0, 1
"""当前索引"""
current_num =0
while current_num < all_num:
# print(a)
yield a
a, b = b, a+b
current_num +=1
"""【return:返回】"""
return "ok!"
# creatr_num(10)
"""!!!函数里有yield,它的(调用函数)
,变为创建一个生成器的对象!!!"""
obj2 = creatr_num(2)
"""希望创建多个生成器的对象"""
# for num in obj:
# print(num)
while True:
try:
ret =next(obj2)
print("!!!obj2!!!:", ret)
except Exception as ret:
"""打印0k"""
print(ret.value)
break
七、40_2通过send唤醒生成器
"""使用生成器执行fibonaqi数列"""
def creatr_num(all_num):
a, b =0, 1
"""当前索引"""
current_num =0
while current_num < all_num:
ret =yield a
print(">>>ret>>>", ret)
a, b = b, a+b
current_num +=1
# creatr_num(10)
"""!!!函数里有yield,它的(调用函数)
,变为创建一个生成器的对象!!!"""
obj = creatr_num(10)
"""希望创建多个生成器的对象"""
# for num in obj:
# print(num)
"""send一般不要放到最前面"""
# obj.send("hehehe")
# obj = send(None)
ret =next(obj)
print(ret)
ret = obj.send(3)
print(ret)
八、41_使用yield完成多任务
"""生成器实现多任务:!!!重点!!!"""
import time
def task_1():
while True:
print('---1---')
time.sleep(0.1)
"""yield:回到next"""
yield
def task_2():
while True:
print('---2---')
time.sleep(0.1)
yield
def main():
"""此时是创建生成器"""
t1 = task_1()
t2 = task_2()
while True:
next(t1)
next(t2)
if __name__ =="__main__":
main()
九、迭代器_生成器
迭代器: 减少内存空间,实现循环。
生成器: 让一个函数 (暂停执行),想继续执行
可以调用next或send。
迭代器和生成器保存的都是生成数据的代码,
而不是具体的数据。