欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python生成器generator和迭代器Iterator测试

程序员文章站 2024-02-12 12:44:43
...

为什么需要使用生成器?

'''
generator生成器
通过列表推导式,我们可以创建一个新的列表,但是,受内存限制,列表的容量是有限的。
而且,创建一个包含100万个元素的列表,不仅占用很大存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都
白白浪费。所以,如果列表元素可以按照某种算法推算出来,那么我们是可以在循环的过程中不断推算出后续的元素。
这样就不必创建完整的list,从而节省大量的空间。在python中,这种一遍循环一遍计算的机制,称为生成器:generator。

得到生成器的方式:
1、通过列表推导式得到一个生成器
'''

测试01

# [x for x in range(1000000000)]
#[0,3,6,9,12,15,18,21,......,27]
newlist = [x*3 for x in range(10)]
#得到生成器
g = (x*3 for x in range(30))
print(type(g)) #generator
#方式一:通过调用__next__()方式得到元素
#每调用一次产生一个一个元素
print(g.__next__())
print(g.__next__())
#方式二:next() 系统内置函数builtins
#每调用一次产生一个一个元素
print(next(g))
print(next(g))
print(next(g))

测试02

g = (x*3 for x in range(30))

while True:
    try:
        e = next(g)
        print(e)
    except:
        print('没有更多元素了')
        break

#定义生成器的方式二:借助函数生成

#斐波那切数列

#yield就是一个生成器
def func():
    n=0
    while True:
        n += 1
        yield n


g = func()

# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))

def fib(length):
    a,b =0,1
    n=0
    while n<length:
        yield b  #return b + 暂停
        a,b = b,a+b
        n += 1

    return '没有更多元素了' #return 就是得到StopIteration的提示信息

g = fib(8)
print(next(g))
print(next(g))

测试03

'''
生成器方法:
__next__():获取下一个元素
send(value):向每次生成器调用中传值 注意:第一次调用send(None)

'''
def gen():
    i = 0
    while i < 5:
        tem = yield i   #return + 暂停  tem = 1或者2
        print('tem',tem)
        i += 1

    return '没有更多数据'


g = gen()

#g.__next__()
#为什么第一次一定要传一个NONE值,第一次还没进入yeild,不能传值
print(g.send(None))
g1 = g.send("1")
print(g1)
g2 = g.send("2")
print(g2)

04生成器应用

'''
#进程 > 线程 > 协程(一个进程包含多个线程,一个线程包含多个协程)
#迅雷可以设置线程个数
#生成器应用

'''

def task1(n):
    for i in range(n):
        print('正在搬第{}块砖!'.format(i))
        yield  None


def task2(n):
    for i in range(n):
        print('正在听第{}首歌!'.format(i))
        yield None

g1 = task1(10)
g2 = task2(5)
#交替完成
while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        pass


'''
定义生成器方式:
1、通过列表推导方式
g = (x+1 for x in range(6))
2、函数 yeild
def func():
    ...
    yeild

g =func()

产生元素:
1、next(generator)  ---> 每次调用都会产生一个新的元素,如果元素产生完毕,再次调用的话就会产生异常
2、生成器自己的方法:
   g.__next__()
   g.send(value)
   
应用:协程
'''

生成器总结:

'''
定义生成器方式:
1、通过列表推导方式
g = (x+1 for x in range(6))
2、函数 yeild
def func():
    ...
    yeild

g =func()

产生元素:
1、next(generator)  ---> 每次调用都会产生一个新的元素,如果元素产生完毕,再次调用的话就会产生异常
2、生成器自己的方法:
   g.__next__()
   g.send(value)
   
应用:协程
'''

 迭代器测试:

#可迭代的对象:1、生成器 2、元组 列表 集合 字典 字符串
#如何判断一个对象是否是可迭代的?
from collections import Iterable

list1 = [1,4,7,8,8]
f = isinstance(list1,Iterable) #判断列表是否可迭代
print(f)

# f1 = isinstance('abc',Iterable)
# f2 = isinstance(100,Iterable)

g = (x+1 for x in range(10))
f3 = isinstance(g,Iterable)
'''
迭代是访问集合元素的一种形式。迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
迭代器只能往前不会退后。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
只要调用next(),得到下一个元素,就是迭代器
生成器是可以迭代的,也是迭代器
list是可以迭代的,但是不是迭代器,但是可以把他变成一个迭代器iter()
元组、列表、集合、字典、字符串通过iter()转换成迭代器
'''
lit1 = [1,2,3,4]
lit = iter(lit1)

print(next(lit))
print(next(lit))

注意:

生成器是可以迭代的,也是迭代器
list是可以迭代的,但是不是迭代器,但是可以把他变成一个迭代器iter()
元组、列表、集合、字典、字符串通过iter()转换成迭代器