python 代码生成器,怎样用python自动生成python代码

  python 代码生成器,怎样用python自动生成python代码

  生成器在python中是一个很实用的工具,但由于其他主流编程语言中没有“生成器”的概念,所以经常被忽略。

  那么使用发电机有什么好处呢?我觉得有两个好处:一个是减少内存的使用,一个是简化代码,可以增强代码的可读性

  举个栗子,比如生成斐波那契数列。如果使用生成器而不是列表,代码大致如下:

  def fib(n): prev,cur=0,1 RES=[]while n 0:n-=1 RES . append(cur)prev,cur=cur,prev cur return resprint(fib(10))# Out:[1,1,2,3,5,8,3,21,34,55]如上面的代码所示,如果使用list的数据结构,那么需要在内存中保存10个int类型的数据。你可能会说这才40字节,所以无所谓;但如果这个类型参数n的输入值是1000000000(十亿)的话,就要占用4GB左右的内存,不容易被计算机吃掉。

  所以,对于数据量巨大的数据,使用链表显然是要消耗大量内存的。发电机在这里很有用。我不需要一下子拿到那么多数据,用的时候拿出来就行了。

  如果用生成器来实现斐波那契数列,代码可以改写为:

  def fib(n): prev,cur=0,1 while n 0: n -=1 yield cur prev,cur=cur,prev cur g=fib(10)print([I for I in g)])# Out:[1,1,2,3,5,8,13,21,34,55]上面的代码是用生成器函数得到一个生成器(有两种方法可以构建生成器,下面会介绍)。从上面的代码可以看出,生成器函数中有一个关键字yield,这是这个函数是生成器函数的标志。yield可以返回值(类似return);另外,每次执行到yield,相当于对这个函数的状态进行挂起,也就是暂时停止执行(不是完全结束),需要一个事件来唤醒这个函数。

  而唤醒这个功能的事件是迭代器协议中的next()。我们知道,生成器满足迭代器协议,即可以调用内置的next()函数来获取下一个元素的值。在python中,对迭代器进行for循环相当于连续调用其next()函数,直到迭代器的下一项为空,此时将抛出StopIteration。

  所以每次执行for循环,就相当于在满足迭代器的对象G上做next()。此时,让行后已经暂停的函数将被唤醒,生成器函数将继续向下执行。这样我们可以看到生成器可以大大节省内存空间,因为生成器是一个根据需要生成数据的对象,每次调用next()只返回当前需要的值,而不是保存整个序列的信息;同时,上面的生成器代码显然更加简洁。

  以下代码可能更有助于理解next()和hang:

  def array(n):for I in range(10):print( before return ,i) yield i print(after return ,I)g=array(10)print(g)#g表示生成器对象的地址# out:generator object array at0x 115 a 4 e 10 brint(next(g)) before return 00 print(next(g)) before return 0 before 11 print(next(g)) return 1之后return 22之前 从上面的代码可以看出,当第一个当第二次执行next()函数时,生成器函数被唤醒,从上一次停止继续执行。

  创建生成器的两种方法中的第一种是使用生成器函数(关键字yield),上面已经介绍过了,这里不再赘述。

  第二种是生成器表达式,比如求2的n次方的序列。代码可以写成:

  G1=(pow (2,x)for x in range(10))print([I for I in G1])# out:[1,2,4,8,16,32,64,128,256,512]类似于生成列表的方式,只是方括号改成了圆括号。

  注意python中的生成器只能被遍历一次。请看下面的代码:

  G1=(pow (2,x)for x in range(10))print([I for I in G1])# out:[1,2,4,8,16,32,64,128,256,512] print ([I for I in G1]) # out因为第一次遍历后,结束位置已经被指向,第二次遍历将没有结果。

  总结python generator的优点是节省内存,简化代码;

  生成器的构造方式有两种:生成器函数(包括yield关键字)和生成器表达式(括号);

  生成器满足迭代器协议,即可以通过next()函数访问下一个值。如果使用yield关键字,则在返回值时暂停生成器函数,直到next next()唤醒函数,然后继续从刚才停止的地方向下执行。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: