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

第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循环内部如何处理列表这类内置序列类型的:

$ python2
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "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__方法,因此不需要想这样返回一个不同的对象:

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

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

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> L = [1,2,3]
>>> iter(L) is L
False
>>> 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)
>>> r
range(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循环内部如何处理列表这类内置序列类型的:

$ python2
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "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__方法,因此不需要想这样返回一个不同的对象:

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

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

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> L = [1,2,3]
>>> iter(L) is L
False
>>> 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)
>>> r
range(0, 10)
>>> list(r)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

map、zip和filter迭代器
字典视图迭代器

其他迭代器主题

本章小结

习题解答

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值