列表生成式、生成器、迭代器。

列表生成式,需求把列表[0,1,2,3,4,5,6,7,8,9]每一个元素加1。

#列表生成式  list generration
#第一种方法
a = [0,1,2,3,4,5,6,7,8,9]
b = []
for i in a:
    b.append(i+1)

print(b)

#第二种方法
c = [i+1 for i in a]
print(c)

#第三种方法
for index,i in enumerate(a):
    a[index] +=1

print(a)


#通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,
不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
 

   生成器 如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

L = [i*2 for i in range(10)]  #列表生成式
print(L)

g = (i*2 for i in range(10))  #创建一个生成器,仅仅把列表中括号改成小括号。
print(g)
g.__next__()

      1、生成器只有在调用的时候才会产生数据。

      2、生成器取值只能往后取值,不能跨步取值和后退取值。

g = (i*2 for i in range(10))  #创建一个生成器,仅仅把列表中括号改成小括号。

print(g.__next__()) #一般不采用此种方法进行调用,如果调用值超过了生成器的值那么分出现报错。
for n in g:     #使用for循环进行调用并且不会出现超出值而报错。
    print(n)

     我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

def fib(max):
    n,a,b, = 0,0,1
    while n <max:
        #print(b) #这种方式还不叫生成器,距离生成器只有一步之遥了。
        yield (b)
        a,b = b,a+b
        n = n+1
  returan "------none-----"
g = fib(10) #给以给生成器赋值进行调用。 for i in g: print(i)

 

如果执行报StopIteration可以用下面这段代码进行抓错。

while True:
    try:
        x =next(g)  #此处会去调用生成器一直调用到出错会被下面的except给抓到
        print("g",x) 
    except StopIteration as e:   #只有当报StopIteration  as(赋名)给 e 
        print("Generrator return value",e.value)
        break

 迭代器

可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:.

a = [1,2,3]
print(dir(a)) #用内置函数可以查看可用的调用方式。
 
from collections import Iterable #判断是否为迭代器对象

print(isinstance([],Iterable))  #判断是否为迭代器对象
#输出结果
True
print(isinstance([-1,0,1],Iterable))#判断是否为迭代器对象
#输出结果
True
print(isinstance(0,Iterable))#判断是否为迭代器对象
#输出结果
False

from collections import Iterator    #判断是否为迭代器
print(isinstance([x for x in range(5)],Iterator))   #判断是否为迭代器
#输出结果
False
print(isinstance(iter([x for x in range(5)]),Iterator)) #判断是否为迭代器
#输出结果

 

posted @ 2017-11-11 23:59  Byron-He  阅读(231)  评论(0编辑  收藏  举报