一、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() 方法来随时退出 生成器。