专栏首页大数据入坑指南Python自学成才之路 生成器的使用

Python自学成才之路 生成器的使用

为何需要生成器? 假如现在有一个需求,需要打印从1到1亿的整形。如果我们采用普通的方式,直接调用range函数,那么程序肯定会崩溃,因为range(1,100000000)函数直接产生一个从1-1亿的列表,这个列表中的所有数据都是存放在内存中的,会导致内存爆满。这时候我们可以采用生成器来解决这个问题,生成器不会一次性把所有数据都加载到内存中,而是在循环的时候临时生成的,循环一次生成一个,所以在程序运行期间永远都只会生成一个数据,从而大大节省内存。

生成器是什么? 使用yield的函数是生成器,生成器是一个迭代器。

创建一个生成器 在函数中使用yield来创建一个生成器。如下所示:

def my_gen(start, end):
    index = start
    while index < end:
        yield index
        index += 1


print(isinstance(my_gen(1, 100), Iterable))

ret = my_gen(1, 10)
for x in ret:
    print(x)

怎么去理解生成器呢?可以理解为每次使用next获取生成器的值的时候会在yield出暂停并返回值,再次使用next取数时从yiled处开始执行。所以next会在yield处暂停,也在yield处被唤醒。

Send函数 send方法和next方法类似,可以用来触发生成器的下一个yield,但是send不仅可以触发下一个yield,还可以发送数据过去,作为yield表达式的值,yield表达式的值是None。

def my_gen(start):
    while start < 10:
        temp = yield start
        print(temp)
        start += 1


ret = my_gen(1)
# 在迭代开始的地方使用send只能传递None为参数
print(ret.send(None))
print(next(ret))
print(next(ret))
print(ret.send("hello"))
print(next(ret))

注意:使用send的时候,在迭代开始的地方使用send只能传递None为参数。

提前终止生成器 return语句会触发StopIteration异常,可以提前终止生成器。

def my_gen(start):
    while start < 3:
        yield start
        start += 1
        return "hello"

# 如果使用for遍历 不会出现StopIteration异常
ret = my_gen(1)
iter = my_gen(1)
while True:
    print(next(iter))
输出:
Traceback (most recent call last):
  File "D:/pycharm workspace/oopdemo/iterator_generator/generator_demo01.py", line 58, in <module>
    print(next(iter))
StopIteration: hello
1

注意:使用next会抛出StopIteration异常,for循环遍历不会抛出StopIteration异常。

生成器的应用 使用生成器创建一个斐波拉契数列。

def fib(count):
    a, b = 0, 1
    tmp = 1
    while tmp <= count:
        yield b
        c = b
        b = a + b
        a = c
        tmp += 1

for x in fib(7):
    print(x)

上面是生成器的常见的用法,实际上生成器还有一些高级的用法,后面会结合一些场景做介绍。

本人是做大数据开发的,在微信上开了个个人号,会经常在上面分享一些学习心得,原创文章都会首发到公众号上,感兴趣的盆友可以关注下哦!

大数据入坑指南

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python自学成才之路 迭代器的使用

    可迭代对象 实现了__iter__魔术方法的对象是可迭代对象(Iterable)

    我是李超人
  • python自学成才之路 列表,元组,集合详细用法

    python列表使用[]表示,它实际上是一个数组,但是和一般数组不同的地方在于它内部封装了很多很好用的方法(比如append,pop)以及一些特性(比如切片,不...

    我是李超人
  • Python自学成才之路 多线程开发

    1.创建线程 Python中提供了threading模块来创建线程,创建方式有两种。

    我是李超人
  • Python生成器对象send()方法用法

    关于生成器基本用法请参考详解Python生成器函数和生成器对象的原理和用法 >>> def f(): yield from 'abcdefg' #使用yie...

    Python小屋屋主
  • 【翻译】ES6生成器简介

    原文地址:http://davidwalsh.name/es6-generators ES6生成器全部文章: The Basics Of ES6 Generat...

    寒月十八
  • 详解Python生成器函数和生成器对象的原理和用法

    包含yield语句的函数可以用来创建生成器对象,这样的函数也称生成器函数。yield语句与return语句的作用相似,都是用来从函数中返回值。与return语句...

    Python小屋屋主
  • python生成器函数的执行过程

    py3study
  • 一文搞懂《链表反转》

    翻转链表一直都是热门题目,笔者就在某大型互联网公司的面试题中碰到过这种题目,这种题目很常常见,相对应的变形和扩展也很多,今天我们就来攻克它吧。

    lucifer210
  • python生成器函数的应用场景举例---为copy过程添加进度条显示

    生成器的特点是可以迭代,通过dir 查看生成器的方法, 其中有next , send 方法,我们如果调用其next或者send方法都可以获得其下一个元素的值,我...

    qsjs
  • Python迭代器与生成器

    当执行生成器的__next__的时候,代码会按照顺序去执行,当执行到yield时会返回并提出,yield后面的值就是返回值,然后记录代码执行的位置,并退出

    py3study

扫码关注云+社区

领取腾讯云代金券