专栏首页python3Python学习之迭代器和生成器

Python学习之迭代器和生成器

迭代器

在Python如果一个对象可被循环(遍历)该对象中每一个元素的过程叫做迭代。例如 ,字典、字符串、列表、元祖、集合等。他们可被迭代的原因是,都有一个共同的内置函数__iter__。通过执行内置对象的__next__函数,可以依次打印该对象的所有元素。例如 有一个列表,该列表存储了1-100的数值,但是我们只想打印前50的个元素。

 1 flag=True
 2 l=[x for x in range(1,101)]
 3 
 4 l_iter = l.__iter__()
 5 while flag:
 6     try:
 7        item=l_iter.__next__()
 8        if item==51:
 9            flag=False
10            break
11        else:
12            print(item)
13 
14     except:
15         break

在While循环中迭代器将一直循环执行__next__()函数,但迭代器本身并不知道它要迭代多少个元素。当执行到最后元素时,还会继续执行__next__()函数,但此时没有元素可被迭代了,由于迭代器找不到可被迭代元素,将会报错。因此我们在使用while循环时,配合异常捕获代码 try except一起使用,当迭代过程中出现异常,将会自动停止下一次循环。

用迭代器生成列表(2.7版本有效)

 1 class TestIterator:
 2     value=0
 3     def next(self):
 4         self.value+=1
 5         if self.value>10: raise StopIteration
 6         return self.value
 7     def __iter__(self):
 8         return self
 9 ti=TestIterator()
10 ret=list(ti)
11 print(ret)

输出结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

生成器:

假设我们 有个需求,除第一个 和第二个元素外,其他元素依次为前两个元素之和。

我们可以这样写

 1 def fib1(max):
 2     n,a,b=0,0,1
 3     while n<max:
 4         print(b)
 5         a,b=b,a+b
 6         n=n+1
 7     return 'done'
 8 
 9 a=fib1(5)
10 print(a)

输出结果

1 1
2 1
3 2
4 3
5 5
6 done

推导过程如图

用另外一种方法

1 def fib2(max):
2     n,a,b=0,0,1
3     while n<max:
4         yield b
5         a,b=b,a+b
6         n=n+1
7     return 'done'

调用该函数

1 a=fib2(5)
2 print(a)

输出结果 1 <generator object fib at 0x0000000002800518>

此时我们发现,不能像之前那样直接显示结果,此时定义的fib并不是一个简单的函数,而是被改造成了生成器。如果想知道生成的结果可以依次执行__next__函数,但每次只返回一个结果,当没有更多的元素可以被迭代时将会抛出异常。

另外我们也可以使用for 循环和while(需配合try  except使用)打印结果。

1 a=fib2(5)
2 for c in a:
3     print(c)

显示输出结果 1 1 2 3 5.

使用生成器的好处:生成器是根据推导的过程计算下一个元素。再看前两个函数 fib1 和fib2 ,fib1在计算机中开辟一个固定的内存空间用于存储完整的计算结果,但如果我们想访问计算结果中的某一个元素,就需要先遍历整个计算结果,才能通过对象下标或者用for 循环和if条件判断 拿到我们想要的结果,这样做的可以实现我们的需求,但将会耗损较多的内存空间。而fib2则是依据推算过程计算出下一个元素,因此我们就可以在未创建完整对象之前获取我们想要的元素。从而降低内存消耗。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CSS属性汇总--(6) 定位属性3

             right 属性规定元素的右边缘。该属性定义了定位元素右外边距边界与其包含块右边界之间的偏移。

    py3study
  • #5 逆序输出列表内容

    看到逆序输出,想必第一反应就是列表里的第一个元素与最后一个元素交换,接着第二个元素与倒数第二个元素交换......但是有没有更加Pythonic的方法,有,那就...

    py3study
  • python generator

    详细解释参考http://blog.donews.com/limodou/archive/2006/09/04/1028747.aspx

    py3study
  • 一文解开可迭代对象和迭代器的神秘面纱

    可迭代对象和迭代器是两种不同的数据类型,它们都在我们的编程中时常可以遇到。当然他们之间也有很大的关联,接下来就让我们把它们搞定。

    sergiojune
  • 使用FirefoxSend搭建一个临时文件分享系统

    说明:Firefox Send是Firefox推出的一個全新的临时文件分享系统,不过貌似代码开源了,也有几个小伙伴搭建的时候遇到了点问题,要博主发个教程,这里就...

    栖枝perch
  • 迭代器执行流程

    py3study
  • PHP性能规范

    如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍。

    sunsky
  • Numpy中找出array中最大值所对应的行和列

    Python特别灵活,肯定方法不止一种,这里介绍一种我觉得比较简单的方法。 如下图,使用x == np.max(x) 获得一个掩模矩阵,然后使用where方...

    卡尔曼和玻尔兹曼谁曼
  • java之学习集合的并发修改及案例

    吾爱乐享
  • python—多线程

      线程时应用程序中工作的最小单位,python中提供了threading模块来对多线程操作,一般多核cpu采用多进程方式,单核才采用多线程方式

    py3study

扫码关注云+社区

领取腾讯云代金券