复习3

,如何判断一个对象是可迭代对象呢?方法是通过 collections 模块
的 Iterable 类型判断:
>>> from collections import Iterable >>> isinstance('abc', Iterable) # str 是否可迭代

Python 内置的 enumerate 函数可以把一个 list 变成索引-元素对,这样就
可以在 for 循环中同时迭代索引和元素本身:
>>> for i, value in enumerate(['A', 'B', 'C']):

列表生成式即 List Comprehensions

for 循环后面还可以加上 if 判断,这样我们就可以筛选出仅偶数的平方:
 
>>> [x * x for x in range(1, 11) if x % 2 == 0]

还可以使用两层循环,可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'XYZ'] ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

列表生成式也可以使用两个变量来生成 list:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' } >>> [k + '=' + v for k, v in d.items()] ['y=B', 'x=A', 'z=C']

  如果列表元素可以按照某种算法推算出来,那我们是否可以在循
环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从

而节省大量的空间。在 Python 中,这种一边循环一边计算的机制,称
为生成器:generator。

要创建一个 generator,有很多种方法。第一种方法很简单,只要把一个
列表生成式的[]改成(),就创建了一个 generator:

generator 保存的是算法,每次调用 next(g),就计算出 g 的
下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出
StopIteration 的错误。

这种不断调用 next(g)实在是太变态了,正确的方法是使用
for 循环,因为 generator 也是可迭代对象:

我们创建了一个 generator 后,基本上永远不会调用 next(),而是
通过 for 循环来迭代它,并且不需要关心 StopIteration 的错误。

如果推算的算法比较复杂,用类似列表生成式的 for
循环无法实现的时候,还可以用函数来实现。

最难理解的就是 generator 和函数的执行流程不一样。函数是顺
序执行,遇到 return 语句或者最后一行函数语句就返回。而变成
generator 的函数,在每次调用 next()的时候执行,遇到 yield 语句返回,
再次执行时从上次返回的 yield 语句处继续执行。

但是用 for 循环调用 generator 时,发现拿不到 generator 的 return 语句
的返回值。如果想要拿到返回值,必须捕获 StopIteration 错误,返回值
包含在 StopIteration 的 value 中:

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

生成器都是 Iterator 对象,但 list、dict、str 虽然是 Iterable,却不是
Iterator。
把 list、dict、str 等 Iterable 变成 Iterator 可以使用 iter()函数:

凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next()函数的对象都是 Iterator 类型,它们表示一个惰性
计算的序列;
集合数据类型如 list、dict、str 等是 Iterable 但不是 Iterator,不过可
以通过 iter()函数获得一个 Iterator 对象。

猜你喜欢

转载自www.cnblogs.com/charles7987/p/10161855.html