伯乐在线的这个文章非常好,
完全理解 Python 迭代对象、迭代器、生成器
另外python的魔法函数一定要熟悉,初步了解和使用可以看
全面深入了解 Python 魔法函数
要完全理解可以看《流畅的python》,本文也做了一些引用。
我这里只是按自己思路做一个概述与总结,例子相关链接里有。
魔法函数
魔术方法(magic method)是形如method具有前后双下划线(dunder method,即double underline)的方法。这类方法是一般不直接调用,而是在“特殊的句法”时
由Python框架去调用并激活一些基本对象操作。
在创建类时,实现这些方法能让类拥有不同的特性。
比如,在自定义类里实现len方法,你就能计算该类对象的len(obj),实现item方法,就能使用下标获取值obj[index]
实际开发时,往往很大的精力会投入在设计实现魔法函数上。
迭代器、生成器等概念
容器和可迭代对象都是通俗叫法,不是某种数据结构。
容器(container)
“当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器”。
绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力。比如bloom filter是容器却不可迭代。
可迭代对象(iterable)
“凡是可以返回一个迭代器的对象都可称之为可迭代对象”。
“迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了iter方法,该方法返回一个迭代器对象。”迭代器对象obj_it实现了next方法,可以通过next(obj_it)来获取容器遍历中的下一个元素。
当运行代码:
x = [1, 2, 3]
for elem in x:
...
实际执行情况是:
迭代器(iterator)
迭代器就是实现了工厂模式的对象,它在你每次你询问要下一个值的时候给你返回。
“有很多关于迭代器的例子,比如itertools函数返回的都是迭代器对象”。
生成器(generator)
生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写iter()和next()方法了,只需要一个yiled关键字。
生成器在Python中是一个非常强大的编程结构,可以用更少地中间变量写流式代码,此外,相比其它容器对象它更能节省内存和CPU,当然它可以用更少的代码来实现相似的功能。现在就可以动手重构你的代码了,但凡看到类似:
def something():
result = []
for ... in ...:
result.append(x)
return result
都可以用生成器函数来替换:
def iter_something():
for ... in ...:
yield x
生成器表达式(generator expression)
“生成器表达式是列表推倒式的生成器版本,看起来像列表推导式,但是它返回的是一个生成器对象而不是列表对象。”
>>> a = (x*x for x in range(10))
>>> a
<generator object <genexpr> at 0x401f08>
>>> sum(a)
285
列表/集合/字典推导式(list,set,dict comprehension)
创建与使用: python的各种推导式(列表推导式、字典推导式、集合推导式)
可以看到比较熟悉的列表推导式的[]改为()即可得到生成器,改为{}则是集合推导式。
生成器和推导式区别在于推导式一次性生成了一个列表、字典、集合对象,而非返回一个可迭代对象,数据量大就不能使用推导式了。