Python的生成器(generator)
2017-09-30 18:12
411 查看
如果函数要产生一系列结果,那么最简单的做法是把这些结果放在一份列表(list)中,并将其返回给函数调用者。例如我们要获得一份文本中每个单词的长度。
输入验证下:
输出结果:
这个get_word()函数本身没有问题,但是有2个方面值得注意,一是这个函数稍显拥挤,需要预先定义一个列表,然后在循环中添加元素,最后返回,并不是很简练,当然这不是什么大问题。二是当你有大量数据并把所有值放在内存时,这种处理方式可能并不是很好,例如text文本非常大,有好几个GB,就无法使用这种方式了。
这时,需要用到生成器(generator),生成器就是使用yield表达式的函数,使用很简单,直接把你函数需要返回的列表内容前面加上yield即可。如上面那个函数,改写如下:
可以看到,这个改写后的函数清晰了许多,没有列表的定义、添加元素、返回列表等,列表中的元素,现在都分别传给yield了。看看试验结果:
输出:
这和最开始的函数得到的结果是一致的。
生成器的优点是它无须将对象的所有元素都存入内存后,才开始进行操作。而是仅在迭代至某个元素时才会将该元素放入内存。这个特点使得它特别适合用于遍历一些巨大序列对象,例如大文件、大集合、大字典等。这个特点也被称为延迟计算或惰性求值(lazy evaluation),可以有效的节省内存空间。
例如,如果直接对文件对象调用read()方法,会导致不可预测的内存占用。可以用生成器读取固定长度的缓冲区,不用将文件一次性读入内存。
总结下:
所有需要返回序列对象的函数都可以使用生成器。
使用生成器比收集结果放入列表然后返回的方式更加简练清晰。
生成器函数返回的是一个迭代器,可以把传给yield些值,逐次产生出来。
生成器不会影响内存的消耗,特别适合于处理大数据文件、大的数据对象等。
def get_word(text): result = [] for i, letter in enumerate(text.split(' ')): result.append(len(letter)) return result
输入验证下:
text = 'Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation.' print(get_word(text))
输出结果:
[4, 5, 5, 4, 1, 5, 9, 2, 5, 8, 6, 2, 5, 6, 6, 3, 12, 13]
这个get_word()函数本身没有问题,但是有2个方面值得注意,一是这个函数稍显拥挤,需要预先定义一个列表,然后在循环中添加元素,最后返回,并不是很简练,当然这不是什么大问题。二是当你有大量数据并把所有值放在内存时,这种处理方式可能并不是很好,例如text文本非常大,有好几个GB,就无法使用这种方式了。
这时,需要用到生成器(generator),生成器就是使用yield表达式的函数,使用很简单,直接把你函数需要返回的列表内容前面加上yield即可。如上面那个函数,改写如下:
def gen_get_word(text): for i, letter in enumerate(text.split(' ')): yield len(letter)
可以看到,这个改写后的函数清晰了许多,没有列表的定义、添加元素、返回列表等,列表中的元素,现在都分别传给yield了。看看试验结果:
print(list(gen_get_word(text)))
输出:
[4, 5, 5, 4, 1, 5, 9, 2, 5, 8, 6, 2, 5, 6, 6, 3, 12, 13]
这和最开始的函数得到的结果是一致的。
生成器的优点是它无须将对象的所有元素都存入内存后,才开始进行操作。而是仅在迭代至某个元素时才会将该元素放入内存。这个特点使得它特别适合用于遍历一些巨大序列对象,例如大文件、大集合、大字典等。这个特点也被称为延迟计算或惰性求值(lazy evaluation),可以有效的节省内存空间。
例如,如果直接对文件对象调用read()方法,会导致不可预测的内存占用。可以用生成器读取固定长度的缓冲区,不用将文件一次性读入内存。
def read_file(path): with open(path, 'rb') as f: while True: block = f.read(1024) if block: yield block else: return
总结下:
所有需要返回序列对象的函数都可以使用生成器。
使用生成器比收集结果放入列表然后返回的方式更加简练清晰。
生成器函数返回的是一个迭代器,可以把传给yield些值,逐次产生出来。
生成器不会影响内存的消耗,特别适合于处理大数据文件、大的数据对象等。
相关文章推荐
- python高级特性(生成器generator )
- Python_生成器(generator)
- python 生成器generator
- python yield generator (迭代器 生成器 协程) 理解
- 我的python3基础笔记之 【生成器 generator】 05
- python生成器generator
- Python学习笔记 - 生成器generator
- 【Python】迭代器(iterator) vs 生成器(generator)
- python 生成器 generator
- Python学习笔记(10)-生成器generator和迭代器Iterator
- Python 生成器详解 generator
- Python生成器generator之next和send运行流程
- python生成器Generator
- Python学习笔记 - 生成器generator
- python高级特性-生成器(generator)
- python 学习之 generator(生成器)生成杨辉三角
- 【Python】用生成器generator简单实现杨辉三角
- Python中的生成器(generator)
- python生成器generator用法实例分析
- Python关键字yield把函数变为generator生成器