列表生成式:

[i*2 for i in range(10)]

生成[0,2,4,6,8,10,12,14,16,18]

注:列表生成式可以直接生成列表,但是当数据量特别大的时候,会特别占内存,而且不需要的内容也会占用到空间。
生成器:节省内存空间,只有在调用到的时候才会生成数据
节省内存方式:只记录当前的数据位置,之前的数据会释放。只有一个next方法:_next_()
要创建一个generator,有很多种方法。第一种方法只要把一个列表生成式的[]改成(),就创建了一个generator:
eg:

a=[ i * i for  i in range(10)]
print(a)
b=( i * i for  i in range(10))
print(b)
输出:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr>> at 0x02126240>>

eg:输出斐波那契数列的前N个数:
函数方法:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        '''t = (b, a + b) # t是一个tuple
        a = t[0]
        b = t[1]'''
        n = n + 1
    return 'done'
fib(5)

生成器方法:

def fib(max):
    n,a,b = 0,0,1
    while n < max:
        #print(b)
        yield  b
        a,b = b,a+b
        n += 1
    return '-----done-----'#功能是异常时打印消息
f=fib(5)
print(f)
输出:<generator object fib at 0x02126210>>
print(f.__next__()) #逐行执行并打印
print(f.__next__())
print("干点别的事")
print(f.__next__())
输出:
1
1
干点别的事
2

注:
1.generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
2.在循环过程中不断调用yield,就会不断中断。把函数改成generator后,我们基本上不会用next()来获取下一个返回值,而是直接使用for循环:

for n in fib(6):
    print(n)

用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

def fib(max):
    n,a,b = 0,0,1
    while n < max:
        #print(b)
        yield  b
        a,b = b,a+b
        n += 1
    return '-----done-----'
f=fib(5)
g = fib(6)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break
输出:
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: -----done-----
正文到此结束

本文标题:Python函数和常用模块-生成器

本文链接:https://www.hantaosec.com/317.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源及链接,不带链接禁止任何转载!访问任何网络安全相关文章,则视为默认接受网络安全文章免责声明 ,请认真阅读。

喜欢我的文章吗?
别忘了点赞或赞赏,让我知道创作的路上有你陪伴。