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

可迭代对象和迭代器

可迭代对象:内置方法有__iter__方法的

  像基本数据类型:list, dict, tuple, str都是可迭代对象。但同时,他们没有__next__,所以不能叫做迭代器。

迭代器:内置方法有__iter__和__next__的

  因为迭代器都有__iter__,所以,迭代器都是可迭代对象。

  可迭代对象执行__iter__之后,返回的是一个迭代器。

* 文件对象(文件句柄)里面既有__iter__, __next__, 文件对象执行__iter__之后,还是文件对象本身。文件对象本身就是一个迭代器。

* 迭代器对象无论执行多少次__iter__, 得到的都会是一个迭代器对象。

for循环的本质:

  1、将in 后面的可迭代对象,调用__iter__,返回一个迭代器对象。

  2、循环调用迭代器的__next__方法

  3、捕捉异常 StopIteration, 跳出__next__循环。

迭代器的优缺点:

  优点:不占内存空间、不依赖索引

  缺点:不能精确找值、会报错。

生成器

  我们自己造的迭代器叫生成器。生成器里面的代码块不会执行,除非调用__next__方法。

关键字yield:

  yield提供了一种自定义生成器方式

  yield会暂停函数的运行

  yield返回任意数据类型

  yield后面跟的值就是我们调用__next__方法后得到的值

yield与return的异同点:

  相同点:都可以返回值,都可以返回多个值

  不同点:

    yield能重复返回多次,函数不会结束运行。

    return只能返回一次,返回一次后,函数运行结束

生成器表达式: g = (i for i in range(1, 10000000) if i != 4)

  生成器表达式,用两个小括号括起来。

1、利用生成器重写range

def my_range(start, stop, step=1):

    while True:
        if start < stop:
            yield start
            start += step
       else:
            break

2、面试题

def add(n,i):
    return n+i
def test():
    for i in range(4):
        yield i
g=test()

for n in [1,10]:
    g=(add(n,i) for i in g)

print(n)
res=list(g)

A. res=[10,11,12,13]
B. res=[11,12,13,14]
C. res=[20,21,22,23] 
D. res=[21,22,23,24]

重点:生成器不会执行函数体内代码,除非调用__next__
原文地址:https://www.cnblogs.com/KbMan/p/11190662.html