Python学习笔记 - 迭代器Iterator

来源:互联网 发布:罗杰疑案知乎 编辑:程序博客网 时间:2024/06/05 14:39

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

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

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

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

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

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

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

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

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

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

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

你可能会问,为什么listdictstr等数据类型不是Iterator

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是Iterable但不是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
demo

#!/usr/bin/env python3# -*- coding: utf-8 -*-from collections import Iterable, Iteratordef g():    yield 1    yield 2    yield 3print('Iterable? [1, 2, 3]:', isinstance([1, 2, 3], Iterable))print('Iterable? \'abc\':', isinstance('abc', Iterable))print('Iterable? 123:', isinstance(123, Iterable))print('Iterable? g():', isinstance(g(), Iterable))print('Iterator? [1, 2, 3]:', isinstance([1, 2, 3], Iterator))print('Iterator? iter([1, 2, 3]):', isinstance(iter([1, 2, 3]), Iterator))print('Iterator? \'abc\':', isinstance('abc', Iterator))print('Iterator? 123:', isinstance(123, Iterator))print('Iterator? g():', isinstance(g(), Iterator))# iter list:print('for x in [1, 2, 3, 4, 5]:')for x in [1, 2, 3, 4, 5]:    print(x)print('for x in iter([1, 2, 3, 4, 5]):')for x in iter([1, 2, 3, 4, 5]):    print(x)print('next():')it = iter([1, 2, 3, 4, 5])print(next(it))print(next(it))print(next(it))print(next(it))print(next(it))d = {'a': 1, 'b': 2, 'c': 3}# iter each key:print('iter key:', d)for k in d.keys():    print('key:', k)# iter each value:print('iter value:', d)for v in d.values():    print('value:', v)# iter both key and value:print('iter item:', d)for k, v in d.items():    print('item:', k, v)# iter list with index:print('iter enumerate([\'A\', \'B\', \'C\']')for i, value in enumerate(['A', 'B', 'C']):    print(i, value)# iter complex list:print('iter [(1, 1), (2, 4), (3, 9)]:')for x, y in [(1, 1), (2, 4), (3, 9)]:    print(x, y)




1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 喂母乳母亲奶头裂开怎么办 给宝宝吃奶被吃到奶头裂开怎么办 宝宝吃奶奶头裂开了怎么办 小孩吃奶奶头裂开了怎么办 站久坐久腰酸痛怎么办 孕39周胎儿头小怎么办 怀孕腰两侧长肉怎么办 怀孕四个月半月吃点就饱怎么办啊 怀孕四个月睡眠不好怎么办 二胎七个月肚子太大怎么办 上火牙疼牙龈肿怎么办 孕30周乳房胀痛怎么办 怀孕长妊娠纹了怎么办 坐久了肚子胀疼怎么办 怀孕后胖的太快怎么办 怀孕牙齿全坏了怎么办 怀孕脸胖了好多怎么办 孕晚期不爱吃肉怎么办 怀孕期间胖了怎么办啊 孕期长得太胖怎么办 狗吃马肉脸肿了怎么办 狗过敏了脸肿了怎么办 孕初期外阴很痒怎么办 怀孕了吃了田鸡怎么办 孕妇睡眠质量差怎么办吃什么 39周2天了还不生怎么办 孕中期体重猛长怎么办 4个半月胎位不正怎么办 41周不产生宫缩怎么办 生完孩子胎盘没有脱落怎么办 39周还是臀位怎么办 怀孕7个月胎位不正怎么办 怀孕六个多月胎位不正怎么办 怀孕七个月了胎位不正怎么办 怀孕七个月胎位不正怎么办 怀孕肚子上有妊娠纹怎么办 怀孕九个月肚子长痱子怎么办 怀孕前体重偏胖怎么办 怀孕打胰岛素血糖控制不好怎么办 孕后期憋的难受怎么办 怀孕6个月不想生怎么办