Python的迭代器和生成器

103 阅读5分钟
原文链接: zm12.sm-tc.cn

Python迭代器和生成器

2009年01月24日 23:33:00

      Python的迭代器和生成器

      一、迭代器Iterators
      迭代器仅是一容器对象,它实现了迭代器协议。它有两个基本方法:
      1)next方法
      返回容器的下一个元素
      2)__iter__方法
      返回迭代器自身
       迭代器可使用内建的iter方法创建,见例子:
      >>> i = iter('abc')
      >>> i.next()
      'a'
      >>> i.next()
      'b'
      >>> i.next()
      'c'
      >>> i.next()
      Traceback (most recent call last):
      File "<string>", line 1, in <string>
      StopIteration:
      class MyIterator(object):
      def __init__(self, step):
      self.step = step
      def next(self):
      """ Returns the next element."""
      if self.step==0:
      raise StopIteration
      self.step-=1
      return self.step
      def __iter__(self):
      """Returns the iterator itself."""
      return self
      for el in MyIterator(4):
      print el
      --------------------
      结果:
      3
      2
      1
      0
      二、生成器Generators
      从Python2.2起,生成器提供了一种简洁的方式帮助返回列表元素的 函数来完成简单和有效的代码。
      它基于yield指令,允许停止函数并立即返回结果。
      此函数保存其执行上下文,如果需要,可立即继续执行。
      例如Fibonacci函数:
      def fibonacci():
      a,b=0,1
      while True:
      yield b
      a,b = b, a+b
      fib=fibonacci()
      print fib.next()
      print fib.next()
      print fib.next()
      print [fib.next() for i in range(10)]
      --------------------
      结果:
      1
      1
      2
      [3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
      PEP Python Enhancement Proposal Python增强建议
      tokenize模块
      >>> import tokenize
      >>> reader = open('c:/temp/py1.py').next
      >>> tokens=tokenize.generate_tokens(reader)
      >>> tokens.next()
      (1, 'class', (1, 0), (1, 5), 'class MyIterator(object):/n')
      >>> tokens.next()
      (1, 'MyIterator', (1, 6), (1, 16), 'class MyIterator(object):/n')
      >>> tokens.next()
      (51, '(', (1, 16), (1, 17), 'class MyIterator(object):/n')
      例子:
      def power(values):
      for value in values:
      print 'powering %s' %value
      yield value
      def adder(values):
      for value in values:
      print 'adding to %s' %value
      if value%2==0:
      yield value+3
      else:
      yield value+2
      elements = [1,4,7,9,12,19]
      res = adder(power(elements))
      print res.next()
      print res.next()
      --------------------
      结果:
      powering 1
      adding to 1
      3
      powering 4
      adding to 4
      7
      保持代码简单,而不是数据。
      注意:宁可有大量简单的可 迭代函数,也不要一个复杂的一次只计算出一个值的 函数
      例子:
      def psychologist():
      print 'Please tell me your problems'
      while True:
      answer = (yield)
      if answer is not None:
      if answer.endswith('?'):
      print ("Don't ask yourself too much questions")
      elif 'good' in answer:
      print "A that's good, go on"
      elif 'bad' in answer:
      print "Don't be so negative"
      free = psychologist()
      print free.next()
      print free.send('I feel bad')
      print free.send("Why I shouldn't ?")
      print free.send("ok then i should find what is good for me")
      --------------------
      结果:
      Please tell me your problems
      None
      Don't be so negative
      None
      Don't ask yourself too much questions
      None
      A that's good, go on
      None