python_学习笔记0825

来源:互联网 发布:c语言continue和break 编辑:程序博客网 时间:2024/05/21 17:09

今天是二零一伍年八月二十五日

1、在python中有像list、tuple这样的对象,他们是可迭代的(Iterable),这样的对象在for语句中被循环。但是我们都知道,list是一个有限的对象。也就是说,其实当list被创建以后,他是具有长度的,每一个元素在内存中都是有位置的。但是有时候,在一个list里面,我们有时候只需要前面几个元素,这样就造成了大量内存浪费。为了防止这种浪费,我们就需要一种新的数据类型——生成器(generator)

顾名思义,生成器是动态生成内容的,比如:

l = [x * x for x in range(10)]g = (x *x for x in range(10) )

把原来的方括号修改为圆括号,就是我们的生成器了。g的列举更加灵活:
>>> next(g)0>>> next(g)1>>> next(g)4>>> next(g)9>>> next(g)16>>> next(g)25>>> next(g)36>>> next(g)49>>> next(g)64>>> next(g)81>>> next(g)Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration

next()语句帮助我们一步一步的“计算”生成器中的值。生成器中保留的其实是一种算法和计数器,每次使用next时,就计算下一个元素的值。当然,在我们的算法里也有一个上限,所以我们在访问到最后就会有StopIteration的异常被抛出。当然我们的生成器也可以像其他可迭代对象一样被for循环直接输出。

但是有时候,生成一个有逻辑的序列却并不是那么简单。比如斐波那契数列,我们们能仅仅用列表生成器就生成吗?不行,这个时候必须使用函数:

# generator.pydef fib(max):n , a , b = 0 , 0 , 1while n < max : print(b) a , b = b , a + b  n += 1  return 'done'

那么我们能用生成器生成一个动态斐波拉切吗,答案是可以的。那么我们就来分析一下斐波拉切函数,在这个函数里,我们真正需要的其实是b这个变量,而print这个函数正好是输出了这个变量。所以,想要把这个函数变成生成器,我们要从这里入手,我们只用把打印语句改成yield b就行,也就是这样:
# generator.pydef fib(max):n , a , b = 0 , 0 , 1while n < max : yield b a , b = b , a + b  n += 1  return 'done'

这个时候我们再尝试去使用这个函数的时候就不一样了。

g = fib(6)

此时的g就是一个生成器了,我们使用next或者是for循环就能打印出我们的斐波拉切数列。但是我们看回我们的定义,发现我们还有一个done被return了,那么它到底什么时候被返回呢?这个我想大家不用想也知道,它会在我们原先被抛出异常的时候返回,也就是:

Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration: done

当然要是我们想正常输出这个done的话,我们就需要捕获异常了


2、刚刚在使用生成器的时候使用了Next句柄,那么,是否还有其他的对象也可以使用next?答案是当然的,这样的对象我们统一称为——迭代器(Iterator)。那么我们的list、string是迭代器吗?答案是否定的,关于这一点我们可以使用isinstance函数去检验。他们只是可迭代的(Iterable),远不是迭代器。不过没有关系我们可以使用iter()函数使它变成迭代器。

>>> from collections import Iterator>>> isinstance((x for x in range(10)), Iterator)True>>> isinstance([], Iterator)False>>> isinstance({}, Iterator)False>>> isinstance('abc', Iterator)False


>>> isinstance(iter([]), Iterator)True>>> isinstance(iter('abc'), Iterator)True

那么为什么我们所钟爱的这些数据类型不能成为迭代器呢?因为我们所称的迭代器往往是一个数据流,它往往需要next函数去一个一个计算下一个值。有时候我们称迭代器是惰性的,只有当我们需要下一个数据的时候他才会计算。









0 0
原创粉丝点击