python 迭代器、生成器、递归

生成器

  通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。这时生成器的优势就出来了,他只会依次一个的取出数据,而非一次性全部生成。

>>> l = [ x for x in range(10)]    #列表生成
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> m = (x for x in range(10))    #生成器
>>> m
<generator object <genexpr> at 0x0000000000D44048>
>>> next(m)
0
>>> next(m)
1
>>> next(m)
2
...
>>> next(m)   #取到最后,报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

  l和m的区别在于l是一个列表,而m是一个generator对象,需要使用next方法(迭代器)去一个一个取出数据,而不会一次性全部返回。同时,生成器也可以使用一次行遍历出所有数据

>>> m = (x for x in range(10))
>>> for i in m:
...     print(i)
...
0
1
2
3
4
5
6
7
8
9
>>>

  生成器可以使用于算法推导,如著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到

>>> def f(max):
...     n,a,b = 0,0,1
...     while n < max:
...         yield b
...         a,b = b,a+b
...         n = n+1
...
>>> f
<function f at 0x0000000000D3BD08>
>>> m = f(6)
>>> next(m)
1
>>> next(m)
1
>>> next(m)
2

迭代器:

  迭代器:是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 

  优点:对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。

  另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。

>>> m = (x for x in range(10))    #生成器
>>> m
<generator object <genexpr> at 0x0000000000D44048>
>>> next(m)   #next则为迭代器的一个方法
0
>>> next(m)
1
>>> next(m)
2
...
>>> next(m)   #取到最后,报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

  迭代器,遇到yield就记录当前位置,下次从当前位置开始

>>> def f():
...     print(111)
...     yield 0
...     print(222)
...     yield 1
...     print(333)
...     yield 2
...
>>> ret = f()
>>> r1 = ret.__next__()
111
>>> print(r1)
0
>>> r1 = ret.__next__()
222
>>> r1 = ret.__next__()
333
>>> r1 = ret.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

递归

  递归,直接或间接调用自身的一种方法。一个函数在内部调用自身本身,这个函数就是递归函数。

>>> def f(n):
...    if n == 1:
...        return 1
...    return n * f(n-1)
...
>>> ret = f(5)
>>> print(ret)
120
>>>

  

 

posted on 2016-06-09 11:20  逸秋  阅读(67)  评论(0)    收藏  举报

导航