《Python学习手册》学习笔记(14)之第14章迭代器和解析,第一部分(关键词:编程语言/Python/迭代器/解析/迭代器协议)

来源:互联网 发布:企业网站cms 编辑:程序博客网 时间:2024/06/07 06:47

第14章 迭代器和解析,第一部分

写在开头的读者笔记

值得一读的小节

1.迭代器:初探

1.1.迭代器:初探 - 文件迭代器

迭代协议:有__next__方法的对象会前进下一个结果,而在一系列结果的末尾时,则会引发StopIteration。在Python中,任何这类对象都认为是可迭代的iterable)。任何这类对象也能以for循环或其他迭代工具遍历,因为所有迭代工具内部工作起来都是在每次迭代中调用__next__,并且捕捉StopIteration异常来确定何时离开。

迭代器for循环的版本,在Python中是以C语言的速度运行的,而while循环版本则是通过Python虚拟机运行Python字节码的,可能运行得更慢一些。

1.2.迭代器:初探 - 手动迭代:iter和next

Python3.0提供了内置函数next,它会自动调用一个对象__next__方法。给定一个可迭代对象 X,调用next(X)等同X.__next__()

>>> f = open('script1.py')>>> f.__next__()'import sys\n'>>> f.__next__()'print(sys.path)\n'>>> f.__next__()'x = 2\n'>>> f.__next__()'print(2 ** 33)'>>> f.__next__()Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration>>> f = open('script1.py')>>> next(f)'import sys\n'>>> next(f)'print(sys.path)\n'>>> next(f)'x = 2\n'>>> next(f)'print(2 ** 33)'

迭代协议还有一点值得注意。当for循环开始时,会通过它传给iter内置函数,以便从可迭代对象获得一个迭代器返回的对象含有需要的next方法。for循环内部如何处理列表这类内置序列类型的:

$ python2Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> L = [1,2,3]>>> I = iter(L)>>> I.next()1>>> I.next()2>>> I.next()3>>> I.next()Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration

最初的一步(应该是指调用iter方法)对于文件来说不是必需的,因为文件对象就是自己的迭代器。也就是说,文件自己的__next__方法,因此不需要想这样返回一个不同的对象:

$ python3Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linuxType "help", "copyright", "credits" or "license" for more information.>>> f = open('script1.py')>>> iter(f) is fTrue>>> f.__next__()'import sys\n'

列表以及很多其他的内置对象,不是自身的迭代器,因为它们支持多次打开迭代器。对这样的对象,我们必须调用iter启动迭代

$ python3Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linuxType "help", "copyright", "credits" or "license" for more information.>>> L = [1,2,3]>>> iter(L) is LFalse>>> L.__next__()Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: 'list' object has no attribute '__next__'>>> I = iter(L)>>> I.__next__()1>>> next(I)2

2.Python 3.0中的新的可迭代对象

2.1.Python 3.0中的新的可迭代对象 - range迭代器

在Python3.0中,range函数返回一个迭代器,该迭代器根据需要产生范围中的数字,而不是内存中构建一个结果列表

>>> r = range(10)>>> rrange(0, 10)>>> list(r)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

迭代器:初探

文件迭代器

(读者:
迭代协议:有__next__方法的对象会前进下一个结果,而在一系列结果的末尾时,则会引发StopIteration。在Python中,任何这类对象都认为是可迭代的iterable)。任何这类对象也能以for循环或其他迭代工具遍历,因为所有迭代工具内部工作起来都是在每次迭代中调用__next__,并且捕捉StopIteration异常来确定何时离开。

迭代器for循环的版本,在Python中是以C语言的速度运行的,而while循环版本则是通过Python虚拟机运行Python字节码的,可能运行得更慢一些。

手动迭代:iter和next

(读者:Python3.0提供了内置函数next,它会自动调用一个对象__next__方法。给定一个可迭代对象 X,调用next(X)等同X.__next__()

>>> f = open('script1.py')>>> f.__next__()'import sys\n'>>> f.__next__()'print(sys.path)\n'>>> f.__next__()'x = 2\n'>>> f.__next__()'print(2 ** 33)'>>> f.__next__()Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration>>> f = open('script1.py')>>> next(f)'import sys\n'>>> next(f)'print(sys.path)\n'>>> next(f)'x = 2\n'>>> next(f)'print(2 ** 33)'

迭代协议还有一点值得注意。当for循环开始时,会通过它传给iter内置函数,以便从可迭代对象获得一个迭代器返回的对象含有需要的next方法。for循环内部如何处理列表这类内置序列类型的:

$ python2Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> L = [1,2,3]>>> I = iter(L)>>> I.next()1>>> I.next()2>>> I.next()3>>> I.next()Traceback (most recent call last):  File "<stdin>", line 1, in <module>StopIteration

最初的一步(应该是指调用iter方法)对于文件来说不是必需的,因为文件对象就是自己的迭代器。也就是说,文件自己的__next__方法,因此不需要想这样返回一个不同的对象:

$ python3Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linuxType "help", "copyright", "credits" or "license" for more information.>>> f = open('script1.py')>>> iter(f) is fTrue>>> f.__next__()'import sys\n'

列表以及很多其他的内置对象,不是自身的迭代器,因为它们支持多次打开迭代器。对这样的对象,我们必须调用iter启动迭代

$ python3Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linuxType "help", "copyright", "credits" or "license" for more information.>>> L = [1,2,3]>>> iter(L) is LFalse>>> L.__next__()Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: 'list' object has no attribute '__next__'>>> I = iter(L)>>> I.__next__()1>>> next(I)2

其他内置类型迭代器

列表解析:初探

列表解析基础知识

在文件上使用列表解析

扩展的列表解析语法

其他迭代环境

Python 3.0中的新的可迭代对象

range迭代器

(读者:在Python3.0中,range函数返回一个迭代器,该迭代器根据需要产生范围中的数字,而不是内存中构建一个结果列表

>>> r = range(10)>>> rrange(0, 10)>>> list(r)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

map、zip和filter迭代器

字典视图迭代器

其他迭代器主题

本章小结

习题解答

参考文献:
1.《Python学习手册》。

阅读全文
0 0
原创粉丝点击