Python中的生成器

1、生成器

通过一致的方式遍历序列,例如列表中的对象或者文件中的一行行内容,这是python的一个重要特性。这个特性是通过 迭代器协议 来实现的,迭代器协议 是一种令对象可遍历的通用方式。比如,遍历一个字典,获得字典的键:

dict_1 ={'a':1,'b':2,'c':3}

for key in dict_1:
    print(key)
a
b
c

当你写下 for key in dict_1 的语句时。python解释器首先尝试根据 dict_1 生成一个迭代器:

dict_2 = iter(dict_1)

dict_2
<dict_keyiterator at 0x24a56959688>

迭代器就是一种用于在上下文中(比如for循环)向python解释器生成对象的对象。大部分以列表或列表型对象为参数的方法都可以接受任意的迭代器对象。包括内建方法比如minmaxsum,以及类型构造函数比如listtuple

list(dict_2)
['a', 'b', 'c']

生成器是构造新的可遍历对象的一种非常简洁的方式。普通函数执行并返回单个结果,而生成器则“惰性”地返回一个多结果序列,在每一个元素产生之后暂停,直到下一个请求。如需创建一个生成器,只需要在函数中将返回关键字return替换为yield关键字

def squares(n = 10):
    print('Generating squares from 1 to {0}'.format(n**2))
    for i in range(1,n+1):
        yield i**2

当你实际调用生成器时,代码并不会立即执行:

gen = squares()

gen
<generator object squares at 0x0000024A56928C78>

直到你请求生成器中的元素时,它才会执行它的代码:

for x in gen:
    print(x,end = ' ')
Generating squares from 1 to 100
1 4 9 16 25 36 49 64 81 100 

2、生成器表达式

生成器表达式 来创建生成器更为简单。生成器表达式与列表、字典、集合的推导式很类似,创建一个生成器表达式,只需要将列表推导式的中括号替换为小括号即可:

gen = (x**2 for x in range(10))

sum(gen)
285

上面的代码与下面更为复杂的生成器是相同的:

def make_gen():
    for x in range(10):
        yield x**2
        
sum(make_gen())
285

gen = make_gen()

在很多情况下,生成器表达式可以作为函数参数用于替代列表推导式:

sum(x**2 for x in range(10))
285

dict((i,i**2) for i in range(5))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

3、itertools模块

标准库中的itertools模块是适用于大多数数据算法的生成器集合。例如,groupby可以根据任意的序列和一个函数,通过函数的返回值对序列中连续的元素进行分组:

import itertools
first_letter = lambda x:x[0]
names = ['Alan','Adam','Wes','Will','Albert','Steven']

for letter,names in itertools.groupby(names,first_letter):
    print(letter,list(names)) # names is a generator

A ['Alan', 'Adam']
W ['Wes', 'Will']
A ['Albert']
S ['Steven']
下面是一些有用的itertools函数

combinations( iterable, k):根据iterable参数中的所有元素生成一个包含所有可能K-元组的序列,忽略元素的顺序,也不进行替代;

permutations( iterable, k):根据iterable参数中的所有元素按顺序生成包含所有可能K元组的序列;

groupby( iterable, [ , keyfunc]): 根据每一个独一的key生成(key, subiterator)元组;

product( * iterables, repeat = 1): 以元组的形式,根据输入的可遍历对象生成笛卡尔积,与嵌套的for循环类似:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

格陵Lan丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值