迭代器是一个表示数据流的对象;这个对象每次只返回一个元素。 迭代器的一个优点就是它不要求事先准备好整个迭代过程中所有的元素。 迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。 这个特点使得它特别适合用于遍历一些巨大的或是“无限”的集合。
内置的 iter()
函数接受任意对象并试图返回一个迭代器来输出对象的内容或元素,
并会在对象不支持迭代的时候抛出 TypeError
异常。
Python 有几种内置数据类型支持迭代,最常见的就是列表和字典。
如果一个对象能生成迭代器,那么它就会被称作 iterable
。
lst = range(2)
lst
range(0, 2)
lit = iter(lst)
lit
<range_iterator at 0x7f7c68012d90>
使用迭代器的 next()
方法可以访问下一个元素,如果超出了范围就会返回一个 StopIteration
异常,
事实上Python正是利用一些异常来控制流程的进行。
在 for
循环中,Python将自动调用工厂函数 iter()
获得迭代器,自动调用 next()
获取元素,
还完成了检查 StopIteration
异常的工作。
next(lit)
0
next(lit)
1
还可以利用 list()
或 tuple()
这样的函数把迭代器具体化成列表或元组。
要注意,在程序中迭代器随时发生着变化 ,转换的结果与迭代器中迭代的位置有关系。
lit = iter(lst)
next(lit)
t = tuple(lit)
t
(1,)
序列的解压操作也支持迭代器:如果知道一个迭代器能够返回 N
个元素,
那么可以把他们解压到有 N
个元素的元组:
L = [1, 2, 3]
iterator = iter(L)
a, b, c = iterator
a, b, c
(1, 2, 3)
像 max()
和 min()
这样的内置函数可以接受单个迭代器参数,然后返回其中最大或者最小的元素。
in
和 not in
操作也支持迭代器,
如果能够在迭代器 iterator
返回的数据流中找到 X
的话,则 X in iterator
为真。
很显然,如果迭代器是无限的,则这么做就会遇到问题, max()
和 min()
永远也不会返回;
如果元素 X
也不出现在数据流中,则 in
和 not in
操作同样也永远不会返回。
常用的几个内建数据结构 tuple
、 list
、 set
、字典都支持迭代器,字符串也可以使用迭代操作,
对字典调用 iter()
会返回一个遍历字典的键的迭代器:
info={"name":"Bob","age":18,"ID":123}
for key in info:
print(key, info[key])
name Bob age 18 ID 123
dict()
构造函数可以接受一个迭代器,然后返回一个有限的 (key, value)
元组的数据流:
info1=[("name","Bob"),("age",18),("ID",123)]
dict(iter(info1))
{'name': 'Bob', 'age': 18, 'ID': 123}
文件也可以通过调用 readline()
来遍历,直到穷尽文件中所有的行。
这意味着可以读取文件中的每一行:
filei = open('chapter_Python高级特性_ch0912.ipynb')
filei.readline()
'{\n'
filei.readline()
' "cells": [\n'
filei.readline()
' {\n'
掌握了迭代器的使用后,就要继续讲到函数式编程的另一个工具,生成器。
迭代器的输出有两个很常见的使用方式:
- 对每一个元素执行操作。
- 选择一个符合条件的元素子集。
列表推导式和生成器表达让这些操作更加简明,绝大多数情况下, 遍历一个集合都是为了对元素应用某个动作或是进行筛选。
通过列表推导式,则获得一个 Python 列表。
列表解析,返回 list
:
[x+1 for x in lst]
[1, 2]
通过生成器表达式,则会获得一个迭代器。
(x+1 for x in lst)
<generator object <genexpr> at 0x7f7c681f4a00>
生成器表达式会返回一个迭代器,它在必要的时候计算结果,避免一次性生成所有的值。 这意味着,如果迭代器返回一个无限数据流或者大量的数据,则列表推导式就不太好用了。 这种情况下生成器表达式会更受青睐。
def any(iterable):
for element in iterable:
if element:
return True
return False
Python 2.5 以上版本可用。
以下是 any()
方法的语法:
any(iterable)
参数: iterable
-- 元组或列表。
返回值: 如果都为空、0、 false
,则返回 false
,如果不都为空、0、 false
,则返回 true
。
以下展示了使用 any()
方法的实例:
列表 list
,元素都不为空或 0
。
any(['a', 'b', 'c', 'd'])
True
列表 list
,存在一个为空的元素。
any(['a', 'b', '', 'd'])
True
列表 list
,元素全为 0
, ''
, false
。
any([0, '', False])
False
空列表
any([])
False
空元组
any(())
False