迭代器
可以直接作用于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__()) 显示结果: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':} #pickle可以对整个数据进行二进制存储,例如对一个方法进行存储,这是json做不到的 在进行数据的dumps与loads时,load只会把最近的dump数据取出,所以在文件转储时,一个dump只对应一个load,如果需要进行多个转储,可以将数据存储在不同文件。