首页 > 代码库 > 学习7: 列表生成式,生成器,迭代器,可迭代对象
学习7: 列表生成式,生成器,迭代器,可迭代对象
1) 列表生成式,即创建列表的方式
列表生成式,这里是中括号[]
>>> [x*x for x in range(0,10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> [x * x for x in range(1, 11) if x % 2 == 0] [4, 16, 36, 64, 100] >>> [m + n for m in ‘ABC‘ for n in ‘XYZ‘] [‘AX‘, ‘AY‘, ‘AZ‘, ‘BX‘, ‘BY‘, ‘BZ‘, ‘CX‘, ‘CY‘, ‘CZ‘] >>>
2) 生成器(Generator)
生成器有两种方法:第一个是通过生成器表达式来创建,另外一种是通过定义带有yield的函数来实现。
生成器, 这里是小括号()
>>> (x*x for x in range(0,10)) <generator object <genexpr> at 0x0000000000C15240> >>>
说明:从这个可以看出生成器和列表生成的区别:列表生成式直接返回了表达式的结果列表, 而生成器是一个对象,该对象包含了对表达式结果的计算引用。
前者如果数据量太大时候会占用很大内存,而生成器保存的只是一个计算对象,不会占用很大内存。
如果上述算法比较复杂,不好写在一个(),那么可以使用定义一个包含yield的函数来实现,这个就是第二种实现方法。
如果一个函数定义中包含了yield关键字,这个函数就不再是普通函数,而是一个generator object。
要想调用这个函数,需要使用next()函数,并且遇到yield语句返回(可以把yield理解为return)。例如:
def test(): print "one" yield print "two" yield print ‘three‘ yield t=test() t.next() t.next()
输出结果为:
one
two
[Finished in 0.2s]
说明:首先创建生成器对象实例t,然后通过next方法调用函数,每一次执行到yield语句会被终止,并在下次该实例再次执行next方法时候继续执行。所以第一个next方法打印one,第二个next打印two.
test().next()
test().next()
输出结果为:
one
one
[Finished in 0.2s]
说明:注意必须是同一个实例不断调用next方法,如上这种调用方法达不到想要的效果。
def test(): print "one" yield print "two" return print "testing" yield print ‘three‘ yield t= test() t.next() t.next()
说明:如果生成器中有return,在执行过程中 return,则直接抛出 StopIteration 终止迭代。
def readfile(file_name): seek_option=0 while True: with open(file_name) as f: f.seek(seek_option) data = f.readline() if data: yield data seek_option = f.tell() else: return print readfile(‘README.md‘) file = readfile(‘README.md‘) for data in file: print data for data in readfile(‘README.md‘): print data
说明: 上述定义了一个读取文件的生成器。生成器一般可以和for循环配合使用,这样可以迭代生成器元素,而不使用next方法。
3)迭代器(Iterators)
任何具有__next__()方法的对象都是迭代器。
所以生成器是一种特殊的迭代器,任意一个生成器都属于迭代器。
4)可迭代对象
可迭代对象可以为任意对象,不一定非得是基本数据结构,只要这个对象可以返回一个iterator。
可迭代对象通过iter函数可以转化为迭代器,如下例a是一个可迭代对象,而b是一个迭代器。
实际在for循环的过程中也都是将可迭代对象首先转化成迭代器,然后通过next方法读取元素直到抛出异常。
>>> a=[1,2,3,4] >>> b=iter(a) >>> type(a) <type ‘list‘> >>> type(b) <type ‘listiterator‘> >>> b.next() 1 >>> b.next() 2 >>>
学习7: 列表生成式,生成器,迭代器,可迭代对象