python3 第十八章 - 迭代器与生成器

一、迭代器(Iterator)app

  • 迭代是访问集合元素的一种方式
  • 迭代器是一个能够记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到全部的元素被访问完结束。迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:iter() 和 next()。

 

字符串,列表或元组对象均可用于建立迭代器:函数

实例1:spa

basket = ['apple', 'orange', 'pear', 'banana'] it = iter(basket)  # 建立迭代器对象

# 输出迭代器的下一个元素
print(next(it)) # 输出迭代器的下一个元素
print(next(it))

以上代码,输出:code

apple orange

 

实例2:对象

basket = 'abc' it = iter(basket)  # 建立迭代器对象

print(next(it))  # 输出迭代器的下一个元素

print(next(it))  # 输出迭代器的下一个元素

以上代码,输出:blog

a b

 

一般会和for语句搭配使用,如:内存

basket = 'abc' it = iter(basket)  # 建立迭代器对象
for n in it: print(n)

以上代码,输出:ci

a b c

 

Python中 list,truple,str,dict这些均可以被迭代,但他们并非迭代器。为何?字符串

由于和迭代器相比有一个很大的不一样,list/truple/map/dict这些数据的大小是肯定的,也就是说有多少是可知的。但迭代器不是,迭代器不知道要执行多少次,因此能够理解为不知道有多少个元素,每调用一次next(),就会往下走一步,是惰性的。generator

 

判断是否是能够迭代,用Iterable

from collections import Iterable print('{} 是Iterable?', isinstance({}, Iterable)) print('() 是Iterable?', isinstance((), Iterable)) print('100 是Iterable?', isinstance(100, Iterable))

以上代码,输出:

{} 是Iterable? True () 是Iterable? True 100 是Iterable? False

 

 判断是否是迭代器,用Iterator

from collections import Iterator print('{} 是Iterable?', isinstance({}, Iterator)) print('() 是Iterable?', isinstance((), Iterator)) print('(x for x in range(10)) 是Iterable?', isinstance((x for x in range(10)), Iterator))

 以上代码,输出:

{} 是Iterable? False () 是Iterable? False (x for x in range(10)) 是Iterable? True

凡是能够for循环的,都是Iterable

凡是能够next()的,都是Iterator

集合数据类型如list,truple,dict,str,都是Itrable不是Iterator,但能够经过iter()函数得到一个Iterator对象

Python中的for循环就是经过next实现的

for x in [1, 2, 3, 4, 5]: pass

 等价于

# 先获取iterator对象 
it = iter([1, 2, 3, 4, 5]) while True: try: # 获取下一个值 
        x = next(it) except StopIteration: # 遇到StopIteration就退出循环 
        break

 

 

二、生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

  • 跟普通函数不一样的是,生成器是一个返回迭代器的函数,只能用于迭代操做,更简单点理解生成器就是一个迭代器。
  • 在调用生成器运行的过程当中,每次遇到 yield 时函数会暂停并保存当前全部的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。
def fibonacci(n):  # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0 while True: if counter > n: return
        yield a a, b = b, a + b counter += 1 f = fibonacci(10)  # f 是一个迭代器,由生成器返回生成

什么状况下须要使用 yield?一个函数 f,f 返回一个 list,这个 list 是动态计算出来的(无论是数学上的计算仍是逻辑上的读取格式化),而且这个 list 会很大(不管是固定很大仍是随着输入参数的增大而增大),这个时候,咱们但愿每次调用这个函数并使用迭代器进行循环的时候一个一个的获得每一个 list 元素而不是直接获得一个完整的 list 来节省内存,这个时候 yield 就颇有用。

相关文章
相关标签/搜索