生成式、生成器、迭代器、json、pickl
1. 列表生成式
什么是列表生成式?
列表生成式,是Python内置的一种极其强大的生成list的表达式。现有列表
data = [1,2,3,4,5,6] 我们需要将列表中的数据都加1,之后再把列表打印出来,其中可以用
enumerate实现,如下;
for index,i in enumerate(data)
data[index] +=1
print(data)
res:[2, 3, 4, 5, 6, 7]这是不是看起来繁琐,还有一种版本可以更简洁
data= [i+1 for i in range(7)]
res:[2, 3, 4, 5, 6, 7]
这种看起来是不是简洁一些,这就是列表生成式。
2. 列表生成器
什么是列表生成器?边运算边生成,省空间,省内存
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,有时我们仅仅需要访问前面几个元素,而后面绝大多数元素占用的空间都白白浪费了。
so,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
1 data = [1,2,3,4,5,6] 2 # for index,i in enumerate(data): 3 # data[index]+=1 4 # print(data) 5 6 data = (i+1 if i >4 else i for i in data) 7 8 print(data)#目前打印出data它是一个生成器 9 res:<generator object <genexpr> at 0x1013817d8>
有人要问,怎么才能打印出genrator中的元素呢?可以通过next()函数获得generator的下一个返回值
>>> next(g) 0 >>> next(g) 1 >>> next(g) 4
generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。请看如下代码:
1 data = [1,2,3,4,5,6] 2 # for index,i in enumerate(data): 3 # data[index]+=1 4 # print(data) 5 6 data = (i+1 if i >4 else i for i in data) 7 print(next(data)) 8 print(next(data)) 9 print(next(data)) 10 print(next(data)) 11 print(next(data)) 12 print(next(data)) 13 print(next(data)) 14 15 res:/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/zhangyalei/untitled/The_Five/生成器.py 16 Traceback (most recent call last): 17 1 18 File "/Users/zhangyalei/untitled/The_Five/生成器.py", line 66, in <module> 19 2 20 3 21 print(next(data)) 22 4 23 StopIteration 24 6 25 7 26 27 Process finished with exit code 1
下面练习一下著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到
1, 1, 2, 3, 5, 8, 13, 21, 34,55,89,...
def fb(num):
conut = 0
a,b = 0,1
while conut < num:
tmp = a
a = b
b = a +tmp
print(a)
conut +=1
print("done...")
fb(10)#以下是结果
1
1
2
3
5
8
13
21
34
55
done...这就实现啦比较复杂的运算。现在我们把这变成一个生成器看下面代码
1 def fb(num): 2 conut = 0 3 a,b = 0,1 4 while conut < num: 5 tmp = a 6 a = b 7 b = a +tmp 8 #print(a) 9 conut +=1 10 yield a#在没有加yield之前时这是一个函数,在加之后就是一个生成器了,在yield下面可以加return a ,return 是表明一个函数结束,but 加yield表示返回a不结束,返回给谁,谁在外面调用它就返回给谁; 11 print("done...") 12 fb(10)#生成了一个生成器对象,就是代表推导式准备好了,随时可以处理数据的意思 13 14 l = fb(10) 15 #现在可以通过__next__()方法一直往下查,如下 16 l.__next__() 17 l.__next__() 18 print(l.__next__())#这是一个完整的生成器,
此时yield有两个好处;其中一个在上处体现,还有一个yield实现啦函数的中断,并且保存啦函数的中间执行状态
3.迭代器
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象
在判断一组数据类型是否Iterable需要用到isinstance函数如下;
from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>>
>>> isinstance('sb',Iterable)
True
>>>
>>>
>>> isinstance((s for s in range(10)),Iterable)
True
>>>
>>>
>>> isinstance(100,Iterable)
False
最后定义:可以被__next__()函数调用并且不断返回下一值的对象称为迭代器、Iterator
总结:可以用for循环的对象都是iterbale类型,可用__next__()函数的对象都是Iterator类型,集合数据类型,dict,list,str都是iterable对象,不是iterator,若想变成Iterator可以通过iter()函数变成Iterator。
4.json
#json现在有字典data
data ={
'name':'zhangyalei',
'age': 24,
'sex':'M',
'phone':13733208119
}
#现在想把它写到硬盘上所以现在创建一个文件data.txt
with open('data.txt','w') as F:
F.write(data)
F.close()
Now Error:TypeError: write() argument must be str, not dict硬盘只识别二进制,所以不认识str
we could try:
with open('data.txt','w') as F:
F.write(str(data))
F.close()
现在成功啦,在data.txt中有上面的那个字典信息啦,我们再打开
with open('data.txt','r') as f:
data = f.read()
print(data['age'])
抛出异常:TypeError: string indices must be integers现在我们通过eval将data.txt转成dict
with open('data.txt','r') as f:
data = eval(f.read())
print(data['age'])#Res 24;没有问题 把一个内存对象转换成字符串形式,就叫序列化;把一个字符串转换成内存对象就叫反序列化 为什么 要这么做? 序列化的作用是将内存中的数据持久化对象。

浙公网安备 33010602011771号