迭代器
可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是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
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成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,如果需要进行多个转储,可以将数据存储在不同文件。