Iterator和Generator

一直没有太搞明白Iterator和Generator的异同,在网上找到一个帖子,就抛上来。

http://blog.sina.com.cn/s/blog_490a3781010002rj.html

听说Python也有类似C++ STLiterator,今天看了看,Python的东西真是好懂啊,几分钟就看完了 iterator和genrator的Tutorial。Tutorial一开始先提醒我们for语句是很强大滴,只要是个容器(container),用for就可以遍历里面所有元素。例如:
      for element in [1, 2, 3]:
              print element
      for element in (1, 2, 3):
              print element
      for key in {'one':1, 'two':2}:
              print key
      for char in "123":
              print char
      for line in open("myfile.txt"):
              print line
      然后Tutorial中接着解释,其实for是使用了in后面那个对象的 iterator。每次调用 iterator的next方法都可以得到下一个元素。到了最后一个元素时系统会抛出一个称为StopIteration的Exception,使for语句终止。只要为自己写的类加上__iter__()方法和next()方法,也能够使用for语句来遍历所有元素。具体细节就不讲了,因为这只是引出generator的一个过渡。
      为了使 iterator更直观、生成更简单,Python引入了generator。generator对象可以起到类似container的作用,container中的元素内容由generator中的语句确定。例如:
      def reverse(data):
              for index in range(len(data)-1, -1, -1):
                      yield data[index]
 
      >>> for char in reverse('golf'):
      ...        print char
      ...
      f
      l
      o
      g
      在实现上,generator并不是生成一个列表,然后再由for对元素一个一个进行处理,而是一次只返回一个元素(用yield语句)并保存generator的状态,等下次被调用时再从当前状态往下执行,这样可以省却保存整个大列表的存储代价。
      为了练手,我写了两个等价的程序,它们可以列出某个目录下能找到的所有文件名:

      (1)不用generator:
 
              import os
              def PrintName(fn):
                      print 'Found new file:' + fn
              def ForEachFile(root, func):
                      for dir_entry in os.walk(root): # 对找到的每个目录,os.walk()返回[目录名,子目录列表,文件名列表] (其实os.walk本身就是个generator)
                              for fName in dir_entry[2]:
                                      fFullName = dir_entry[0]+'\\'+fName
                                      func(fFullName)
              ForEachFile('d:\\temp', PrintName)
 
 
      (2)使用generator:
 
              import os
              def RecursiveFileList(root):
                      for dir_entry in os.walk(root):
                              for fName in dir_entry[2]:
                                      yield dir_entry[0] + '\\' + fName
              for fn in RecursiveFileList('d:\\temp'):
                      print 'Found new file: ', fn
 
      对比之下,用了generator的封装更加易懂和易用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值