python的迭代器与生成器_[ python ] 迭代器和生成器

列表生成式

列表生成式是 python 内置的非常简单却强大的可以用来创建list的生成式。

有这样一个需求:

l1 = [1,2,3,4,5,6,7,8,9]    循环每个元素加1

l1 = [1,2,3,4,5,6,7,8,9]

# 使用列表生成式将列表中的各个元素加1

list_num = [x+1 for x in l1]# 这里就是一个列表生成式

print(list_num)

列表生成式可以用一行语句代替循环生成上面的list

迭代器

迭代器表面上看是一个数据流对象或容器,当使用其中的数据时,每次从数据流中取出一个数据,直到数据被取完,而且数据不会被重复使用。

从代码的角度来看,迭代器是实现了迭代器协议方法的对象和类。

迭代器协议方法主要是两个:

__iter__(): 该方法返回对象本身,它是for语言使用迭代器的要求,只要函数含有__iter__就可以说这个函数是可迭代的;

__next__(): 该方法用于返回容器中下一个元素或数据。当容器中的数据用尽时,应该引发 StopIteration 异常一个类只要具有这两种方法,就可以称之为 迭代器,也可以说是可迭代的。

s1 = 'hello world'

print('__iter__' in dir(s1))

print('__next__' in dir(s1))

# 字符串s1包含 __iter__ 方法且不包含__next__方法,所以字符串 s1 只是一个可迭代的类型,并不是一个迭代器

# 执行结果:

# True

# False

s1 = 'hello world'

s2 = s1.__iter__() # 将可迭代类型转换为 迭代器 使用 __iter__()

print('__iter__' in dir(s2))

print('__next__' in dir(s2))

# 使用 __iter__()方法将 s1 字符串转换为迭代器,迭代器既有__iter__方法,又有 __next__方法

# 执行结果:

# True

# True

自定义一个迭代器必须满足:

类中必须要定义 __iter__ 方法和 __next__方法

# 自定义一个迭代器:

class My_iterator(object):

def __init__(self, x, max):

self.mul, self.x = x, x

self.xmax = max

def __iter__(self):

return self

def __next__(self):

if self.x and self.x !=1:

self.mul = self.mul + self.x

if self.mul < self.xmax:

return self.mul

else:

raise StopIteration

if __name__ == '__main__':

myite1 = My_iterator(2, 100)

for i in myite1:

print(i)

迭代器一定是可迭代的, 但是可迭代的不一定是迭代器

生成器

使用生成器可以生成一个值的序列用于迭代,并且这个值的序列不是一次生成的,而是使用一个,再生成一个,可以使得程序节约大量内存。

生成器对象是通过yield关键字定义的函数对象,因此生成器也是一个函数。生成器用于生成一个值的序列,以便在迭代中使用。

自定义生成器:

def foo():

print('1111')

yield 1

print('22222')

yield 2

f = foo()

print('type f:', type(f))

print(f.__next__())

print(f.__next__())

# 执行结果:

# type f:

# 1111

# 1

# 22222

# 2

执行流程如下图:

3c67e8081d384c479bb6164e45218505.png

需要注意的是 yield 是生成器中的关键字,生成器在实例化的时候并不会立即执行,而是等待调用其__next__()方法之后才开始运行,当再次调用__next__()方法会在第一次yield返回值的最后开始执行,不断的调用__next__()方法,直到最终返回 StopIteration 异常为止。

实例1:移动平均值

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#移动平均值

deffoo():'''sum 计算总和

count 计算有几个数

avg 平均数

:yield: 返回计算出的平均数'''sum=0

count=0

avg=0whileTrue:

num= yield avg #接收num,返回avg

sum +=num

count+= 1avg= sum /count

f=foo()

next(f)

ret= f.send(10)print(ret)

ret= f.send(20)print(ret)

ret= f.send(30)print(ret)

ret= f.send(40)print(ret)#执行结果:#10.0#15.0#20.0#25.0

移动平均值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值