生成器表达式 python,python怎么生成

  生成器表达式 python,python怎么生成

  下午看了一点生成器,是python的基础。所以我就不放在我的进阶系列里了。刚吃饱饭没事干,就写一下我对发电机的粗浅认识吧。3354无聊前言

  1.为什么需要一个生成器,原则是先问为什么,再问怎么做?我们先来看看python为什么要加入生成器的功能。

  Python在数据科学领域非常流行。我认为部分功劳是它的发电机。

  我们知道我们可以使用列表来存储数据,但是当我们的数据非常大时,建立一个存储数据的列表会占用大量内存。这就是发电机派上用场的时候。可以说是一种不占用太多计算机资源的方法。

  二。简单的生成器我们可以用列表派生来初始化一个列表(production):

  list 5=[x for x in range(5)]print(list 5)# output:[0,1,2,3,4]我们使用了类似的方式来生成生成器,只不过这次我们将上面的[]替换为():

  gen=(x for x in range(5))print(gen)# output:generator object gen expr at0x 000000000 aa 20 f 8看到上面的print(gen)并没有直接输出结果,而是告诉我们它是一个生成器。那么我们如何称呼这个gen呢?

  有两种方法:

  第一种类型:

  对于gen中的项目:print (item) # output: 01234第二个:

  print(next(gen))# output:0 print(next(gen))# output:1 print(next(gen))# output:2 print(next(gen))# output:3 print(next(gen))# output:4 print(next(gen))# output:trace现在我们可以考虑它背后的原理是什么了。

  从第一次用for调用方法可以知道生成器是迭代的。更准确的说,他是一个迭代器。

  我们可以证实这一点:

  从集合导入迭代,迭代器Print(is instance(Gen,Iterative))# output:true Print(is instance(Gen,Iterator))# output:truestr,list,tuple,dict,set这些都是迭代的,也就是for可以用来访问里面的每一个元素。但它们不是迭代器。

  那什么是迭代器?

  可以理解为我们平时做一件事的步骤。

  例如,我们泡茶:

  首先,我们要烧开水。

  然后,拿出茶具和茶叶。

  然后,当水烧开时,茶就沏好了。

  最后是品茶。

  假设我们定义了一个泡茶函数(迭代器),然后将泡茶步骤的方法封装到这个函数中。每次调用该函数时,都会返回一个步骤,并保存当前的执行状态。如果中间发生了什么,比如到了第二步,突然接了一个电话。当我们调用这个函数时,我们会得到第三步(水开了,我们就开始泡茶),也就是状态保存了。我们可以执行这个泡茶功能,直到所有的步骤都被调用。

  定义一个方法,分步执行,可以保存状态。这是一个迭代器。

  回到上面的第二种访问方法,当我们到达第六次打印(next(gen))时,系统告诉我们Traceback (most recent call last): StopIteration。也就是说,gen的迭代已经到了尾声,不可能再继续迭代了。

  而生成器本身就是一个迭代器

  我们在内部封装了算法,并规定在特定条件下将一个结果返回给调用者。(x for x in range(5))是这样实现的,不是实现(0,1,2,3,4)然后一个一个迭代,而是一个一个生成。这也是next(gen)能起作用的原因。

  3.应用1。如前所述,生成器可以帮助系统在生成大量数据时节省内存。真的是这样吗?通过下面的代码感受一下:decorator的原理会在代码中应用。如果你不懂,那也没关系。有什么作用后面会解释。当然,如果你想知道,可以看看我的另一篇博文:Python Advanced(四):decorator的分析)@

  import time def get _ time(func):def wrapper(* args,* * kwargs):start _ time=time . time()result=func(* args,* * kwargs)end _ time=time . time()print( Spend:,end_time - start_time)返回结果返回wrapper @ get _ time def _ list(n):L1=[list(range(n))for I in range(n)]del ge @ get _ time def _ generator(n):ge=(tuple(range(n))for I in range(n

  题外话:其实上面的get_time函数是我自己经常用的一个函数。我是在我的一个工具包(制作轮子)里面写的,也就是说,如果我想看一个函数的执行时间(测试效率),我只要把get_time decorator放到这个包里面,修饰一下就可以了。所以建议如果找到一个经常使用的功能,可以尝试自己造轮子。我将代码粘贴到这里。

  import time def _ list(n):L1=[list(range(n))for I in range(n)]del l1def _ generator(n):ge=(tuple(range(n))for I in range(n))del gestart _ time=time . time()_ list(1000)End _ time=time . time()print( Spend:,End _ time-start _ time)start _ time=time . time()_ generator(1000)End _ time=time . time()print( Spend:,End _ time-start _ time

  花费:0.04300236701965332花费:0.0分析表明0-999都是在一个列表中生成的,所以需要的时间比较多。

  生成器只是封装了算法,每次调用都调用算法,可以节省内存。

  2 .产出关键词。好吧,前面那个只告诉我们用()创建一个生成器。如果我们想定义自己的生成器函数呢?退货似乎行不通。没关系,python有关键词yield。它的作用类似于return,即返回一个值给调用者,只不过带yield的函数返回值后,函数会保持调用yield的状态,下次被调用时,会在原来的基础上继续执行代码,直到满足下一个yield或者满足结束条件结束函数。

  一个简单的例子:

  test():yield 1 yield 2 yield 3t=test()print(next(t))# output:1 print(next(t))# output:1 print(next(t))# output:1 print(next(t))# output:trace back(最近一次调用last)骚年,存在是合理的,python有生成器也不是不合理。数学中很多算法是无穷的(比如自然数),我们无法一一列举,生成器可以帮助我们。

  比如:杨辉三角。

  这是一个无限列表。我们可以把他的算法封装成一个生成器,只在需要的时候生成,这样就不会占用大量的计算机内存资源。

  给出了以下代码:

  def triangle(): _list,new_list=[],[]while True:length=len(_ list)if length==0:new _ list . append(1)else:for times in range(length 1):if times==new _ list . append(1)Elif times==length:new _ list . append(1)else:temp=_ list[times-1]_ list[times]new _ list . append(temp)yield new _ list #返回值,然后挂起函数,等待下一次调用list=new

  [1][1,1][1,2,1][1,3,3,1][1,4,6,4,1][1,5,10,10,5,1][1,6,15,20,15,6,1][1,7,21,35,35,21,7,1][1,8,28,56,70,56,28,8,1][1,9,36,84,126,126,84

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

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