1 生成器:
为什么要有生成器?
就拿列表来说吧,假如我们要创建一个list,这个list要求格式为:[1,4,9,16,25,36……]这么一直持续下去,直到有了一万个元素的时候为止。如果我们要创建这个list,那么应该是这样的:
[i*i for i in range(1,10001)] #列表生成式,不要忘了 #结果就不列出来了
这样的话,这个list会占用极多的内存,如果我们能只将算法保存在list中,那么这个list所占的内存会大大减小,等我们需要用到list的值的时候,这个list会自动运行其中的算法,将第一个值输出,再次运行时,就会自动输出第二个值,以此类推…… 这个特殊的list就被我们称之为生成器(generator)。
如何创建生成器?
创建生成器有很多方法:
1 第一种方法:
#将list生成式中的‘[’换为‘(’ >>> (i*i for i in range(1,10001)) <generator object <genexpr> at 0x7fb0a69dc6e0> >>> g=(i*i for i in range(1,10001)) #使用next()函数获取g的下一个值 >>> g.next() 1 >>> g.next() 4 >>> next(g) 9 #当没有元素可返回的时候,会报错 >>> g=(i for i in range(1,3)) >>> g.next() 1 >>> g.next() 2 >>> g.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration #实际上,我们不推荐用next()函数,较为常用的是用for循环,实际上for循环的本质就是调用了next()函数。即:首先通过iter()将可迭代的数据转换为可迭代对象,然后调用next() g=(i for i in range(1,11)) for i in g: print(i) #结果为: 1 2 3 4 5 6 7 8 9 10 #这样当没有值可供返回的时候就会退出循环并不会报错。
2 第二种方法:
这种方法用在函数中,比如说用函数实现杨辉三角:
个人实现该函数的代码:
def yh(): l=[1] n=[1] while True: yield n #这里有一个yield关键字!,yield就是定义generator的关键字,yield类似于return,
#当函数运行到这里就会结束,但不同的是,当下次继续运行该函数时,就会从yield下方开始,也就是接续上次运行的地方继续运行。 l.append(0) n=copy.copy(l) #注意这里为什么要用copy功能!!!! for i in range(len(l)): n[i]=l[i]+l[i-1] l=n import copy n=0 for i in yh(): if n==10: break print(i) n=n+1
这里有一个yield关键字!,yield就是定义generator的关键字,yield类似于return,当函数运行到这里就会结束,但不同的是,当下次继续运行该函数时,就会从yield下方开始,也就是接续上次运行的地方继续运行。
另外摘抄了一个比较短小精悍的代码:
def yh(): N = [1] while True: yield N N.append(0) N = [N[i-1] + N[i] for i in range(len(N))] …………
…………
2 迭代器
迭代器有什么用途?
生成器存储了算法,而迭代器则负责一次输出一个该算法的结果。迭代器类似于生成器(事实上,并不仅仅只是生成器)与循环的结合,只不过这个循环“很懒”,一次只输出一个值。
迭代和迭代器的区别:
迭代:
几乎所有的python对象都是可迭代的,像str dict list tuple generator set……等都是可迭代的。
判断一个对象是否可迭代:
>>> from collections import Iterable >>> isinstance([], Iterable) True
迭代器:
可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterable
判断一个对象是否为迭代器对象:
>>> from collections import Iterator >>> isinstance((x for x in range(10)), Iterator) True >>> isinstance([], Iterator) False >>> isinstance({}, Iterator) False >>> isinstance('abc', Iterator) False
生成器就是一个迭代器对象,他可以被next()函数调用。而像其他类型的对象,例如list,dict……需要使用iter()函数将其转换为迭代器对象。
>>> isinstance(iter([]), Iterator) True >>> isinstance(iter('abc'), Iterator) True
本文参考了廖雪峰大神的python教程。详细请阅读:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000