迭代器、可迭代对象、生成器

 

迭代器与可迭代对象

1、定义:

可迭代对象:大部分容器如 list,truples,str,sets是可迭代对象,但是他们不是迭代器。可迭代对象实现了__iter__方法,返回一个迭代器,或者使用iter(“可迭代对象”)返回一个迭代器。

迭代器:迭代器提供了一种不依赖索引取值的方式,这样可以遍历没有索引的可迭代对象,比如字典、集合、文件等等,加载这一个元素至内存中随后释放,相比之下更节省内存,但是我们没有办法获取迭代器的长度,而且只能往后依次取值。遍历的方法使用next(“迭代器”)

2、代码示例

d={'a':1,'b':2,'c':3}
s = d.__iter__()  #s是一个迭代器

p = iter(“可迭代对象”)  #p是一个迭代器

#遍历迭代器

next(p)

next(p)

3、for循环

在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。如下

a = (1, 2, 3, 4)

for key in a:

    print key

首先python对关键字in后的对象调用iter函数迭代器,然后调用迭代器的next方法获得元素,直到抛出StopIteration异常。

4、自定义一个迭代器:

class Fibs:

    def __init__(self):   #初始化

        self.a = 0

        self.b = 1

       

    def __next__(self):    #获取下一个条目

        self.a, self.b = self.b, self.a + self.b

        return self.a

   

    def __iter__(self):    #返回迭代器

        return self

fibs = Fibs()    #产生一个对象

for f in fibs:    #迭代

    if f > 5:

        break

print(f)

>>>8

next(fibs)

>>>13

next(fibs)

>>>21

生成器
1)创建生成器

在一个一般函数中使用yield关键字,可以实现一个最简单的生成器,此时这个函数变成一个生成器函数。

yield与return返回相同的值,区别在于return返回后,函数状态终止,而yield会保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。

2)为何使用生成器

内存使用更加高效。比如列表是在建立的时候就分配所有的内存空间,而生成器仅仅是需要的时候才会产生。如果我们要读取并使用的内容远远超过内存,但是需要对所有的流中的内容进行处理,那么生成器是一个很好的选择。

3)生成器函数的特点

ü  生成器函数包含一个或者多个yield

ü  当调用生成器函数时,函数将返回一个对象,但是不会立刻向下执行

ü  生成器中__iter__()和__next__()方法等是自动实现的,所以我们可以通过next()方法对对象进行迭代

ü  一旦函数被yield,函数会暂停,控制权返回调用者

ü  局部变量和它们的状态会被保存,直到下一次调用

ü  函数终止的时候,StopIteraion会被自动抛出

4)生成器函数构造示例

l  构造循环生成器

逆序yield出对象的元素

def a(my_str):

    length=len(my_str)

    for i in range(length-1,-1,-1):

        yield my_str[i]

for char in a("hello"):

    print(char)

l  生成器表达式

a=(x for x in range(10))

b=[x for x in range(10)]

# 这是错误的,因为生成器不能直接给出长度

# print("length a:",len(a))

# 输出列表的长度

print("length b:",len(b))

b=iter(b)

# 二者输出等价,不过b是在运行时开辟内存,而a是直接开辟内存

print(next(a))

print(next(b)) 

猜你喜欢

转载自www.cnblogs.com/yongfuxue/p/10036768.html
今日推荐