迭代器和生成器

可迭代对象(iterable)[可迭代对象的内部实现了__iter__方法,该方法返回一个迭代器对象]

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> x  =  [ 1 2 3 ]
>>> y  =  iter (x)
>>> z  =  iter (x)
>>>  next (y)
1
>>>  next (y)
2
>>>  next (z)
1
>>>  type (x)
< class  'list' >
>>>  type (y)
< class  'list_iterator' >

迭代器是具有迭代类型,比如list_iteratorset_iterator

举例说明:

1
2
3
=  [ 1 2 3 ]
for  elem  in  x:
     ...

真实的情况是:

反编译该段代码,你可以看到解释器显示地调用GET_ITER指令,相当于调用iter(x)FOR_ITER指令就是调用next()方法,不断地获取迭代器中的下一个元素,但是你没法直接从指令中看出来,因为他被解释器优化过了。

迭代器(itertor)

迭代器是一个带状态的对象,任何实现了__iter__ 和 __next__(python2中实现了next())方法的对象都是迭代器。__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多的元素,则抛出异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class  Fib:
     def  __init__( self ):
         self .prev  =  0
         self .curr  =  1
  
     def  __iter__( self ):
         return  self
  
     def  __next__( self ):
         value  =  self .curr
         self .curr  + =  self .prev
         self .prev  =  value
         return  value
  
>>> f  =  Fib()
>>>  list (islice(f,  0 10 ))
[ 1 1 2 3 5 8 13 21 34 55 ]

Fib既是一个可迭代对象(实现了__iter__方法),又是一个迭代器实现了(__next__方法),实例变量prev和curr用户维护迭代器内部的状态,每一次调用next()方法的时候做两件事:

  1、为下一次调用next()方法修改状态

  2、为当前这次调用生成返回结果

我的终极实例,助你理解迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class  MyIter:
     def  __init__( self , start = 0 , end = 0 ):
         print ( '程序的init' )
         self .start  =  start
         self .end  =  end
     def  __iter__( self ):
         print ( '我在这里制造了一个迭代器' )
         return  self  # 这个地方如果不return self 那么c 就不具备可迭代的能力
     def  __next__( self ):
         print ( '这里调用 __next__方法' self .start)
         if  self .start <  self .end:
             =  self .start
             self .start  + =  1
             return  i
         else :
             raise  StopIteration()
=  MyIter( 0 5 # 代码到这里只是创造了一个迭代器
 
for  in  c: # 代码到这里 会调用__iter__和__next__ 具有迭代的能力
     print (i)
>>>>>>>>>程序的init
我在这里制造了一个迭代器
这里调用 __next__方法  0
0
这里调用 __next__方法  1
1
这里调用 __next__方法  2
2
这里调用 __next__方法  3
3
这里调用 __next__方法  4
4
这里调用 __next__方法  5

生成器(generator)

生成器是一种特殊的迭代器,不过这种迭代器显得更加优雅,生成器不需要写__iter__和__next__方法,只需要一个yield关键字。

生成器一定是迭代器(反之不成立)

生成器表达式(generator expression)

生成器表达式是列表推导式的生成器版本

1
2
3
4
5
>>> a  =  (x * for  in  range ( 10 ))
>>> a
<generator  object  <genexpr> at  0x401f08 >
>>>  sum (a)
285

总结:

* 容器是一系列元素的集合,str、list、set、dict、file、sockets都可以看作是容器

  容器都是可以被迭代的

* 可迭代对象实现了__iter__ 方法,该方法返回一个迭代器对象

* 迭代器持有一个内部状态字段用户记录下次迭代返回值它实现了 __iter__ 和 __next__方法,迭代器不会一次性把所有的元素加载到内存,而是需要的时候才返回结果

* 生成器是一种特殊的迭代器,返回值是通过yeild

本文转自http://www.cnblogs.com/mosson/p/8398187.html#_label0

猜你喜欢

转载自www.cnblogs.com/Hessen/p/8944563.html
今日推荐