生成器
一边循环一边计算称为生成器,generator
生成器记录一个算法
生成器的作用:
比如:存储1-10000中所有的偶数
1、list
列表推导式
更加耗时
更加开销系统内存
2、生成器
存储数据(存数的算法)
使用生成器的好处
1、时间效率高
2、内存开销小
创建生成器相当于使用元组的推导式
● 生成器的其它生成方式:
1、g=(x for x in range(5)) 其实就像是一个元组推导式
2、包含yield关键字的函数,为生成器 yield用在函数中
● 生成器可以生成的元素的访问及注意事项:
1、next(g) 个人理解为指针,指向元素的某个位置,执行一次指针移动一次
2、for循环变量可以输出生成器的每一个值
3、g.–next–() 等同于next(g)
4、g.send 使用send()访问的时候,首个元素必须给None参数,后续元素可以给任意参数
5、不管用哪种方式,超出生成吕生成数据的范围报StopIteration
import time
import sys
# 记录程序开始时间
start_time=time.time()
list1=[x for x in range(2,1000001,2)]
# 记录程序结束时间
end_time=time.time()
print('程序执行时间为%f' % (end_time-start_time))
print('*'*20)
# 生成一个生成器
start_time=time.time()
g=(i for i in range(2,1000001,2))
end_time=time.time()
print('程序执行时间为%f' % (end_time-start_time))
# 上述实验可以看到两种方式生成的可迭代内容效率不同,生成器生成的最快
# 在函数中使用yield创建生成器
def test_yield():
for x in range(5):
yield x
# 用一个变量接生函数产生的生成器,为了记单词这里把变量名弄的长
yield_iteration=test_yield()
print(yield_iteration) # <generator object test_yield at 0x00000180C6A665C0>
# 访问这个生成器
# for i in yield_iteration:
# print(i)
# 另外一种访问方法 next
print(next(yield_iteration)) # 经过循环后个人理解指针没有复位,所以用next访问报StopIteration
# send访问生成器
print(yield_iteration.send('xxx'))
# send里面必须要填参数,参数内容随便,但指针没移动的时候,第一个参数为None
# TypeError: generator.send() takes exactly one argument (0 given)
yield让程序(循环暂停)
# 使用while 再次理解yield用法
def test():
i = 0
while i < 5:
# 赋值运算下次会被执行 yield会使程序停住
temp = yield i
print(temp)
i += 1
# 上面函数循环中把temp打印出来,发现输出的就是在send中传的参数
g = test()
# send方法只是把生成器元素返回出来
print(g.send(None))
print(g.send('s'))
print('*' * 30 + 'yield完成多任务' + '*' * 30)
# 要求 先存钱,再取钱,两个任务交替运行
def yield_test():
while True:
print('存钱')
yield None
def yield_test2():
while True:
print('取钱')
yield None
t1 = yield_test()
t2 = yield_test2()
while True:
t1.__next__()
t2.__next__()
迭代器
迭代器是访问集合元素的一种方式,迭代器是一个可以记录遍历的位置的对象,迭代器只能往前不会后退。
● 可迭代对象 iterable
【单词注释 iterable 可迭代 iteration 迭代重复 yield 屈服 投降 生产 这里是生产的意思】
集合数据类型如 list列表 tuple元组 dict字典 set集合 str字符串等。生成器如带yield的generator 的函数
【单词注释 generator 发电机 这里是生成器的意思】
● 判断对象是否为可迭代对象 iterable
isinstance(list1,Iterable)
【单词注释 instance例子 实例】
● 迭代器iterator
可以被next()函数调用并不断返回一个值的对象称为迭代器
可以使用isinstance(对象,Iterator) 判断对象是否为迭代器
● iter()函数
分别验证将列表,字典元组,字符串转换为迭代器,使用next()进行访问
使用iterable要导入 从collection.abc 中导入
【collection 收藏】
这里3.9以上版本要使用collection.abc来导入 Iterable
from collections.abc import Iterable, Iterator
# 迭代器只能前进不能后退
# 可迭代对象
# 列表
list = [18, 19, 20, '河南']
# 元组
tuple = (8, 9, 20, 40, '南阳')
# 字典
dict = {'姓名': '刘德华', '年龄': 20, '职业': '叫兽'}
# 集合
set = {'江', '湖', '海'}
# 字符串
str = '这里是河南南阳'
# 判断是否为可迭代对象
print(isinstance(list, Iterable)) # True
print(isinstance(tuple, Iterable)) # True
print(isinstance(dict, Iterable)) # True
print(isinstance(set, Iterable)) # True
print(isinstance(str, Iterable)) # True
# 判断是否为迭代器,虽然为可迭代对象,但不是迭代器
print(isinstance(list, Iterator)) # False
print(isinstance(tuple, Iterator)) # False
print(isinstance(dict, Iterator)) # False
print(isinstance(set, Iterator)) # False
print(isinstance(str, Iterator)) # False
# 通过iter()函数,对可迭代对象转换成迭代器
# 转换列表为迭代器
Iterator_list=iter(list)
# 转换元组为迭代器
Iterator_tuple=iter(tuple)
print(isinstance(Iterator_list, Iterator))
print(isinstance(Iterator_tuple, Iterator))