第四节

迭代器

可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:

 

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

  Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

names = iter(('tom','marrry','jack'))
print(names)
print(names.__next__())
print(names.__next__())
print(names.__next__())

1.生成器

def crash_money(amount):
while amount > 0:
amount -= 1
yield 100  #yield会终止方法的执行,直到下一次再次调用迭代器,迭代器会从终止的地方继续执行迭代器,以此循环,直到迭代器执行完毕。
print("取出100块钱")

atm = crash_money(500)
print(atm)
print(atm.__next__())
print(atm.__next__())
print("hahahahahahah")
print(atm.__next__())

显示结果:
<generator object crash_money at 0x0000007502A2B150>
100
取出100块钱
100
hahahahahahah
取出100块钱
100
#迭代器可以保存函数的执行状态,即使是一个循环函数,终止状态后可以处理其他事情,处理完后可以继续执行迭代器方法

2.使用yield实现单线程中的异步并发
import time
def consumer(name):
print("%s准备吃包子" % name)
while True:
baozi = yield
print("包子[%s]来了,被[%s]吃了!" % (baozi,name))

def producer(name):
c1 = consumer("A")
c2 = consumer("B")
c1.__next__()
c2.__next__()
print("老子要开始吃包子啦!")
for i in range(10):
time.sleep(1)
print("做了两个包子")
c1.send(i)
c2.send(i)

producer("cjfpjt")
3.装饰器的实现
例:(非装饰器)
def login(func):
print("passed user verfication...")
return func
def tv(name):
print("Welcome [%s] to tv page!" % name)

tv = login(tv)  #login函数实现了对tv函数的重构,起到了装饰器的作用
tv("cjfpjt")
例:(含装饰器)
def login(func):
def inner(arg):
print("passed user verfication...")
func(arg)
return inner
@login  #装饰器将tv()方法的内存地址做了一个包装
def tv(name):
print("Welcome [%s] to tv page!" % name)


tv("cjfpjt")
显示结果:
passed user verfication...
Welcome [cjfpjt] to tv page!

4.实现带参数的复杂装饰器
def before_fuc(request,kargs):
print(request)

def after_fuc(request,kargs):
print(kargs)

def filter(before_fuc,after_fuc):
def warrp(main_fuc):
def outer(request,kargs):
before_fuc(request,kargs)
main_fuc(request,kargs)
after_fuc(request,kargs)
return outer
return warrp

@filter(before_fuc,after_fuc)
def tv(request,respond):
print("index")

tv("pjt","ttyy")

递归原理及其实现

整个递归结束后,递归结果会一层一层的逐级返回,所以递归会浪费资源。
def calc(n):
print(n)
if n > 1:
res = calc(n/2)
print("res:",res)
print("N:",n)
return n

calc(10)

显示结果:
10
5.0
2.5
1.25
0.625
N: 0.625
res: 0.625
N: 1.25
res: 1.25
N: 2.5
res: 2.5
N: 5.0
res: 5.0
N: 10
递归实现斐波那契数列
def func(arg1,arg2,stop):
if arg1 == 0:
print(arg1,arg2)
arg3 = arg1 + arg2
print(arg3)
if arg3 < 30:
func(arg2,arg3,stop)

func(0,1,30)
显示结果:
0 1
1
2
3
5
8
13
21
34

算法基础之二分查找
def binary_search(data_source,find_n):
if len(data_source) >= 1:
mid = int(len(data_source)/2)
if data_source[mid] > find_n:
print("The number %s you want in left" % find_n)
print(data_source[:mid])
binary_search(data_source[:mid], find_n)
elif data_source[mid] < find_n:
print("The number %s you want in right" % find_n)
print(data_source[mid:])
binary_search(data_source[mid:], find_n)
else:
print(data_source[mid])
print("find data %s" % find_n)
else:
print("Not found........")

if __name__ == '__main__':
data = list(range(1,600,3))
binary_search(data,322)
显示结果:
The number 322 you want in right
[301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508, 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544, 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580, 583, 586, 589, 592, 595, 598]
The number 322 you want in left
[301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400, 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, 439, 442, 445, 448]
The number 322 you want in left
[301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364, 367, 370, 373]
The number 322 you want in left
[301, 304, 307, 310, 313, 316, 319, 322, 325, 328, 331, 334]
The number 322 you want in right
[319, 322, 325, 328, 331, 334]
The number 322 you want in left
[319, 322, 325]
322
find data 322

算法基础之2维数组90度旋转
data = [[i for i in range(4)] for j in range(4)]
print(data)
for aa in data: print(aa)
'''
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2, 3]
[0, 1, 2, 3]

[0, 0, 0, 0]
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
'''

for i in range(len(data)):
for j in range(i,len(data)):
tmp = data[i][j]
data[i][j] = data[j][i]
data[j][i] = tmp
print("----------------------")
for b in data: print(b)

# print("----------------------")
# for b in data:print(b)


正则表达式

import re

m = re.match("abc","abcdefg")
print(m.group())
#从0开始匹配0-10个数字
m = re.match("[0-9]{0,10}","234567tdfsgdf6sg")
print(m.group())
#匹配10个数字
m = re.match("[0-9]{10}","234567tdfsgdf6sg")
if m:
print("-------------"+m)
#从所有变量匹配1-10个数字
m = re.findall("[0-9]{1,10}","28956tdfdf6sg")
if m:
print(m)
#从所有变量匹配1-10个字母
m = re.findall("[a-zA-Z]{1,10}","28956tdfdf6sg")
if m:
print(m)
#所有变量从0开始匹配所有变量
m = re.findall(".*","28956tdfdf6sg")
if m:
print(m)
#所有变量,匹配所有,每个变量为一个字符串
m = re.findall(".","28956tdfdf6sg")
if m:
print(m)
#所有变量从1开始匹配所有
m = re.findall(".+","28956tdfdf6sg")
if m:
print(m)
#查找所有字母
m = re.findall("[a-zA-Z]+","28956td_fd+f6@s%g")
if m:
print(m)
#
m = re.search("\d+","dfg8956tdfdsf6567")
if m:
print(m.group())
#替换所有数字
m = re.sub("\d+","|","dfg89fh56td_fd+f6yh567@s%g")
if m:
print(m)
#只替换前两个
m = re.sub("\d+","|","dfg89fh56td_fd+f6yh567@s%g",count=2)
if m:
print(m)

 数据序列化

 

1.json序列化
import json

info = {
"name":"panjiatao",
"age":25
}

f = open("test.txt","w")
f.write(json.dumps(info))
f.close()


json反序列化
import json

f = open("test.txt","r")
data = json.loads(f.read())
f.close()
print(data)

运行结果:
{'name': 'panjiatao', 'age': 25}

#存储的文件直接以字符串形式保存,取出时候数据恢复,文件内容可直接查看,但是存储的数据只能为字符串格式

2.pickle序列化
import pickle

def sayhi(name):
print("hello",name)

info = {
"name":"panjiatao",
"age":25,
"func":sayhi
}

f = open("test2.txt","wb")
f.write(pickle.dumps(info))
f.close()

pickle反序列化
import pickle

def sayhi(name):
print("hello",name)

f = open("test2.txt","rb")
data = pickle.loads(f.read())
f.close()
print(data["func"]("panjiatao"))
print(data)

运行结果:
hello panjiatao
None
{'name': 'panjiatao', 'age': 25, 'func': <function sayhi at 0x000000668A7B3E18>}
#pickle可以对整个数据进行二进制存储,例如对一个方法进行存储,这是json做不到的

在进行数据的dumps与loads时,load只会把最近的dump数据取出,所以在文件转储时,一个dump只对应一个load,如果需要进行多个转储,可以将数据存储在不同文件。
 
 

 






 

 

posted @ 2017-06-04 14:37  酷酷的狐狸  阅读(195)  评论(0编辑  收藏  举报