python生成器函数_python 生成器函数应用

可迭代的归约函数

什么是归约(合拢、累加)函数?

一个函数,接受一个可迭代的对象,然后返回单个结果

all()、any()和reduce()的区别?

all、any有一项重要的优化措施是reduce函数做不到的:这两个函数会短路(即一旦确定了结果就立即停止使用迭代器)

reversed是生成器函数

sorted和这些归约数只能处理最终会停止的可迭代对象,否则,这些函数会一直收集元素,永远无法返回结果

深入分析iter函数

在python中迭代对象x时会调用iter(x)

可是,iter函数还有一个鲜为人知的用法:传入两个参数,使用常规的函数或任何可调用的对象创建迭代器。

传入两个参数的作用?

第一个参数:必须是可调用对象,用于不断调用(没有参数),产出各个值

第二个参数:是哨符,这是个标记值,当可调用的对象返回这个值时,触发迭代器抛出StopIteration异常,而不产出哨符。

# 使用iter函数掷骰子,直到掷到1点为止

from random import randint

def d6():

return randint(1,6)

>>> d6_iter = iter(d6,1)

>>> d6_iter

>>> for i in d6_iter:

... print(i)

...

3

5

3

2

5

6

5

3

"""分析: iter函数返回一个callable_iterator对象for循环可能运行特别长的时间,但不会打印1,因为1为哨符d6_iter 一旦耗尽就没有用了如果想重新开始,必须再次iter(...),重新构建迭代器"""

# 同样里example

with open('mydata.txt') as fp:

for line in iter(fp.readline, '\n'):

process_line(line)

协程与生成器的区别生成器用于生成供迭代的数据

协程是数据的消费者

协程与迭代无关

注:虽然在协程中会使用yield产出值,但这与迭代无关

yield from

如果生成器函数需要产出另一个生成器生成的值,传统的解决方法是使用嵌套的for循环

def chain(*iterables):

for it in iterables:

for i in it: # it --> 'ABC'

yield i

>>> s = 'ABC'

>>> t = tuple(range(3))

>>> list(chain(s,t))

['A', 'B', 'C', 0, 1, 2]

>>> t

(0, 1, 2)

改进—> 使用yield from

def chain(*iterables):

for i in iterables:

yield from i

>>> list(chain(s, t))

['A', 'B', 'C', 0, 1, 2]

"""分析:yield from i完全代替了内层的for循环yield from 除了代替循环之外,yield from 还会创建通道,把内层生成器直接与外层生成器的客户端联系起来。把生成器当成协程使用时,这个通道特别重要,不仅能为客户端代码生成值,还能使用客户端代码提供的值。"""

用于重新排列元素的生成器函数

使用场景:产出输入的可迭代对象中的全部元素,不过不会以某种方式重新排列。

itertools.groupby和itertools.tee:两个函数会返回多个生成器

reversed函数:是本节中唯一一个不接受可迭代的对象,而只接受序列为参数的函数。(why? reversed函数是从后向前产出元素,而只有序列的长度已知时才能工作,不过,这个函数会按需产出各个元素,因此无需创建反转的副本)

itertools.groupby假定输入的可迭代对象要使用分组标准排序,即使不排序,至少要使用指定的标准分组各个元素

animals = ['lion', 'bear', 'bat', 'duck', 'rat']

animals.sort(key=len)

for length, group in itertools.groupby(reversed(animals), len): # groupby删除产出(key, group_generator)这种形式的元组

print(length, '->', list(group)) # groupby函数返回的生成器要嵌套迭代,外层使用for,内层使用列表推导

Itertools.tee

作用:从输入的一个可迭代对象中产出多个生成器,每个生成器都可以产出输入的各个元素。产出的生成器可以单独使用

list(itertools.tee('ABC'))

>>> from itertools import tee

>>>

>>> g1, g2 = tee('ABC')

>>> g1

>>> list(g1)

['A', 'B', 'C']

>>> list(g2)

['A', 'B', 'C']

>>> next(g1)

Traceback (most recent call last):

File "", line 1, in

StopIteration

>>> g1, g2 = tee('ABC')

>>> next(g1)

'A'

>>> list(g1)

['B', 'C']

>>> list(g2)

['A', 'B', 'C']

>>> list(zip(tee('ABC')))

[(,), (,)]

>>> list(zip(*tee('ABC')))

[('A', 'A'), ('B', 'B'), ('C', 'C')]

>>>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值