您的位置:首页 > 编程语言 > Python开发

【Python学习】python学习手册--第十四章 迭代器和解析 第一部分

2018-03-13 17:47 459 查看

迭代器:初探

for循环可以用于Python中任何序列类型,包括列表,元组以及字符串。实际上,for循环可以用于任何可迭代的对象在Python中所有会从左至右扫描对象的迭代工具都是如此,这些迭代工具包括了,for循环,列表解析,in关系测试以及内置map函数等等。

“可迭代对象”在Python中是一个相当新颖的设计,实际上可迭代就是序列观念的通用化:如果对象是可迭代的,那么再一些迭代工具中,每一次迭代都会返回一个结果对象,这就是可迭代的。

可迭代对象

在Python中任何可迭代的对象都拥有一个方法:__next__方法,该方法会“前进返回”下一个对象结果,而在一系列对象的结尾,返回一个StopIteration异常。任何拥有__next__方法的对象都是认为可迭代的,在迭代工具进行遍历时,都是Python内部对相应对象__next__方法的调用,并捕捉StopIteration异常来停止迭代。

对于一些Python内置对象来说,对象自身并不是迭代器,自身并不包含next方法,他们支持多次打开迭代器。从具体的技术上讲,在迭代工具开始迭代之前,会调用对象的iter函数(可以多次打开迭代器,实现重头开始迭代的效果),该函数返回可迭代对象的迭代器,返回的对象中才会包含需要的next方法。

>>> l
[1, 2, 3, 4]
>>> l1=l.__iter__()        #l对象中是不存在__next__函数的,只有通过iter函数返回的对象才含有next函数。
>>> l1.__next__()
1
>>> l1.__next__()
2
>>> l1.__next__()
3
>>> l1.__next__()
4
>>> l1.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> l2=iter(l)                                  #也可以使用内置的iter函数达到相同的效果。
>>> l2
<list_iterator object at 0x7f8f1941d4e0>
>>> l2.__ne
l2.__ne__(    l2.__new__(   l2.__next__(
>>> l2.__next__()
1
>>> l2.__next__()
2
>>> l2.__next__()
3
>>> l2.__next__()
4
>>> l2.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>


字典的迭代器在迭代环境中,会自动一次返回一个键。直接效果是,我们不再需要调用keys方法来遍历键值。

>>> D={'a':1,'b':2,'c':3}
>> D
{'c': 3, 'b': 2, 'a': 1}
>> for i in D:             #迭代器每一次会返回一个键
...   print(i)
...
c
b
a
>>


迭代协议也用于list函数,以产生一个列表。

>>> range(5)
range(0, 5)
>>> list(range(5))
[0, 1, 2, 3, 4]
>>>


列表解析

列表解析中也存在迭代器:

>>> [i**2 for i in range(5)]
[0, 1, 4, 9, 16]
>>>


列表解析已[]方括号开始,这声明了返回的对象是一个列表,在方括号中存在着一个“反向”的for循环,迭代工具for将迭代器range(5)中的每一个元素依次取出,做相应的处理(i**2),从而返回一个包含每次迭代结果的列表。列表解析比传统的for循环语句执行速度更快,书写起来更简洁,在Python代码中非常常见。

列表解析也常常用于读取文件:

当你想在读取文件内容的同时,去掉每一行末尾的换行符时,你可以使用下面这个高效的列表解析方式:

>>> [line.rstrip() for line in open('filePython.txt')]   #处理方法可以举一反三,换成其它字符串对象的方法
['line1 one', 'line2 two', 'line3 three', '123456', 'abcdefg', '']


Python扫描了文件,并自动构建了一个列表,这是一个很高效的操作,因为大多数工作都是在Python解释器内部完成,这比同效语句有更高的效率。特别针对大文件,列表解析的速度有更加明显的效率。

列表解析的扩展

实际上,列表解析还可以有其它更复杂的嵌套或扩展。

#列表中加入判断,如果不满足判断,则该行字符串将不会读入列表中
>>> [line.rstrip() for line in open('filePython.txt') if "line" in line ]
['line1 one', 'line2 two', 'line3 three']

#读入列表后,再进行删选判断,替换为其它值。
>>> [line.rstrip() if "line" in line else "HAHAHA!" for line in open('filePython.txt') ]
['line1 one', 'line2 two', 'line3 three', 'HAHAHA!', 'HAHAHA!', 'HAHAHA!']

#两个for循环的嵌套,组合字符串的功能
>>> [x+y for x in 'abc' for y in 'xyz']
['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']
>>>


其它迭代环境及注意要点

在对象中从左到右扫描的每种工具都使用了迭代协议。

列表解析、in成员测试、map函数、以及sort,zip内置函数都使用了迭代协议

Python还包含了各种处理迭代的其它内置函数:enumerate根据相对位置来配对可迭代对象中的项。filter函数(会返回参数函数返回值为True的每一项),reduce针对可迭代对象中的成对的项运行一个函数。

实际上,可迭代性在Python中存在很普遍,有很多看似跟迭代没关系的函数或方法,都在Python内部或多或少地涉及到了可迭代操作。

可迭代对象通过iter函数可以返回一个新的对象从而支持多个迭代器,但有的对象(比如zip,filter和map返回的对象)就不能支持相同结果上的多个迭代器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: