Python迭代器与生成器

 一、Python推导式:

推导式comprehensions(又称解析式),是Python的一种独有特性。

推导式是可以从一个数据序列构建另一个新的数据序列的结构体。

共有三种推导:列表推导式、字典推导式、集合推导式

1、列表推导式

用[]生成list

基本格式:variable = [out_exp_res for out_exp in input_list if out_exp == 2]

out_exp_res:  列表生成元素表达式,可以是有返回值的函数。

out_exp in input_list:迭代input_list将out_exp传入out_exp_res表达式中。

if out_exp == 2 : 根据条件过滤哪些值

案例:

1)打印30以内的数字,所有能被3整除的整数的平方

result = [i**2 for i  in range(1,31) if not i%3]

2)推导式嵌套:找到嵌套列表中名字含有2个'e'的所有名字

names = [['Tom','Billy','Jefferson','Andrew','Wesley','Steven','Joe'],['Alice','Jill','Ana','Wendy','Jennifer','Sherry','Elven']]
result = [i for name in names for i in name if i.count('e')>=2]

3)三元运算与列表推导式

#找出100以内是3的倍数且是记述返回本身,偶数就整除2的数
print([i//2 if not i%2 else i for i in range(100) if not i %3 ])

2、字典推导式

字典推导和列表推导的使用方法类似的,把中括号改成大括号。

基本格式:variable = {out_key:out_value for put_key,out_value in input_list if out_exp == 2}

out_key:返回字典结果的key

out_value: 返回字典结果的value

for out_key,out_value in input_list:迭代input_list将out_exp传入out_exp_res表达式中

if our_exp == 2:根据条件过滤哪些值可以

案例:

1)删除key中包含'a'的数据

dic = {'a':1,'b':2,'c':3,'ab':4}
li = {k:v for k,v in dic.items() if 'a' not in k}
print(li,type(li))

3、集合推导式

他跟列表推导式也是类似的。唯一的区别在于它使用大括号{}。

集合推导式,自带去重功能

案例:

1)过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母

q1 = ['a','ab','abc','abcd','abcde']
result = {i.upper() for i in q1 if len(i)>=3}

2)求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数的元组列表

li = [(x,y) for x in range(6) for y in range(6) if not x%2 and y%2]
print(li)0

3)快速更换key和value的值

q3 = {'a':10,'b':34}
li = {y:x for x,y in q3.items()}

4)合并大小写对应的value值,将k统一成小写

q4 = {'B':3,'a':1,'b':6,'c':3,'A':4}
li = {x.lower():q4.get(x.lower(),0)+q4.get(x.upper(),0) for x in q4.keys()}

二、Python可迭代对象

for后面可接可迭代对象(list,set,str,dict,tuple)

list(可迭代对象)

sorted(可迭代对象)

容器:容器是一钟把多个元素组织在一起的数据结果,容器中的元素可以逐个地迭代获取,可以用in,not in关键字判断元素是否包含在容器中。

通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)

可迭代对象:凡是可以返回一个迭代器的对象都可称之为为可迭代对象。

如何确认一个对象是不是可迭代对象:

1)可迭代对象实现了_iter_方法,该方法返回的一个可迭代对象。

2)使用Iterable判断

哪些是可迭代对象:容器、打开状态的files,sockets等

三、python迭代器(iterator)

什么是迭代器:

迭代器是有状态的,可以被next()调用,函数调用并不断返回下一个值的对象称为迭代器。

任何实现了_iter_()和_next_()都是迭代器。

_iter_() 返回迭代器自身        _next_()返回容器中的下一个值

如果容器中没有更多元素了,则抛出StopIteration异常

(for循环取数据遇到StopIteration时,会退出循环)

所有的Iterable均可以通过内置函数iter()来转变为Iterator

凡是可以返回一个迭代器(_iter_) 的对象都可称之为可迭代对象

生成无限序列:from itertools import count

counter = count(start = 1)

从一个有限序列中生成无限序列:from itertools import cycle

weeks = cycle([”周天“,......])

从无限的序列中生成有限序列:from itertools import count,islice

counter = count(start=1)

s = islice(counter,1,10)

迭代器的好处:迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

四、生成器(generator)

什么是生成器:生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器, 不过这种迭代器更加优雅。它不需要手动编写__iter__()和__next__()方法,只需要一个 yiled关键字。

生成器一定是迭代器(反之不成立)

因此任何生成器也是以一种懒加载的模式生成值

生成器表达式:

1、使用()生成generator,将列表推导式的[]改成()即可得到生成器。

2、列表推导式与生成器表达式,定义和使用非常类似,但是在(大量数据出处理时)性能上相差很大

yield关键字:包含yield表达式的函数是特殊的函数,叫做生成器函数,被调用时将返回一个迭代器,调用时可以使用next或者send(msg)

一个生成器中可以有多个yield

一旦遇到yield,就会保存当前状态,暂停运行生成器,然后返回yield后面的值。

当再次调用生成器的时候,会从刚才暂停的地方继续运行,直到遇到下一个yield。

yield关键字:保留中间算法,下次继续执行

案例:

1、yield生成器来实现斐波那契序列

from itertools import islice
def fib():
    prev,curr = 0,1
    while True:
        yield curr
        prev,curr = curr,curr+prev
f = fib()
print(list(islice(f,0,10)))

生成器fib()的执行过程

当执行f=fib()返回的是一个生成器对象,此时函数体中的代码并不会执行,而是首先返回一个iterable对象!

只有显示或者隐示的调用next的时候才会真正执行函数里面的代码

执行到语句yield b时,fab()函数会返回yield后面的值,并记住当前的状态

下次调用next时,程序流会回到yield b的下一条语句继续执行

看起来就好像一个函数在正常执行的过程中被yield中断了数次,每次中断都会通过yield返回当前的跌倒值

由此可以看出,生成器通过关键字yield不断的将迭代器返回到内存进行处理,而不会一次性的将对象全部放入内存,从而节省内存空间

除了可以使用 next() 方法来获取下一个生成的值,用户还可以使用 send() 方法将一个 新的或者是被修改的值返回给生成器。除此之外,还可以使用 close() 方法来随时退出 生成器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值