函數部分
1、必須有一個明確的結束條件;
2、每次進入一層遞歸時,問題規模相比上次遞歸都應有所減少;
---------------------------------------------------------------------------------------
匿名函數總結:
lambda x,y:x+y #return x+y
max(iter,key=lambda)
min(iter,key=lambda)
sorted(iter,key=lambda)
map(lambda,iter)
reduce(lambda,iter)
filter(lambda,iter)
----------------------------------------------------------------------------------
import time
print(time)--------<module ‘time‘ (built-in)>
類似:m=__import__(‘time‘)
print(m)
m.sleep(3)
filter函數:過濾是TRUE值的內容:
示例:
dic=[{‘name‘:‘geon‘,‘age‘:20},
{‘name‘:‘geon2‘,‘age‘:9000},
{‘name‘:‘geon3‘,‘age‘:1000}
]
過濾大於100的字典
a=filter(lambda d:d[‘age‘]>100,dic)
for i in a:
print(i)
reduce:示例:
python中的reduce內建函數是一個二元操作函數,他用來將一個數據集合(鏈表,元組等)
中的所有數據進行下列操作:用傳給reduce中的函數 func()(必須是一個二元操作函數)
先對集合中的第1,2個數據進行操作,得到的結果再與第三個數據用func()函數運算,
最後得到一個結果。
from functools import reduce
l=list(range(100))
print(l)
reduce(lambda x,y:x+y,l)
---------------------------------------------------------------------------------------
常用函數:sum lambda zip() map
map:示例:
name_l=[‘a‘,‘b‘,‘c‘]
map(lambda x:name+‘sb‘,name_l) <------------map + lambda
<----------map(lambda x:‘x--‘,可叠代對象)
l=[1,2,3,4,7]
原實現: [i**2 for i in l ]
print(x)
map 實現: m=map(lambda i:i**2,l)
FOR i in m:
print(i)
print(list(m))
lambda 函數:
匿名函數
lambda k: salaries[k] <-----------------------
冒號:後面相當於return 內容。
salaries={‘a‘:10,‘b‘:20,‘c‘:30}
f=lambda k:salaries[k]
print(f)
print(f(‘c‘)) --------------給一個 key 返回 key 對應的 value
改寫 字典取最大值:
print(max(salaries,lambda k:salaries[k]))
示例1: 返回字典內最大值的 KEY ,比較 字典內的VALUE: <------------------
dic={‘a‘:10,‘b‘:20,‘c‘:30}
def get_value(k):
return dic[k]
print(max(dic,key=get_value))
lamba K:return(dic[key])
示例2: zip
print(dic.keys(),dic.values())
z=zip(dic.keys(),dic.values()) <----------------------
print([i for i in z])
>>>>>
dict_keys([‘c‘, ‘a‘, ‘b‘]) dict_values([30, 10, 20])
[(‘c‘, 30), (‘a‘, 10), (‘b‘, 20)]
----------------------------------------------------------------------------------------------
聲明式編程:
示例2: 列表嵌套字典
res=(line.split() for line in f)
dec=[{‘name‘:j[0],‘prince‘:j[1],‘count‘:j[2]} for j in res]
以上可改成:
res=[]
with open(‘b.txt‘) as f:
for line in f:
l=line.split()
d={}
d[‘name‘]=l[0]
d[‘prince‘]=l[1]
d[‘count‘]=l[2]
res.append(d)
print(res)
示例1:
f=open(‘b.txt‘)
ms=(float(line.split()[-1])*float(line.split()[-2]) for line in f)
sum(ms)
以上可以用生命式替代
money=[]
with open(‘b.txt‘) as f:
for line in f:
goods=line.split()
res=int(goods[-1])*int(goods[-2])
money.append(res)
# prin
print(sum(money))
sum() 可以plus 可叠代對象; ------------------------------
如:sum([1,2,3,4])
numJ_g=(i for i in range(3))
print(sum(numj_g))
------------------------------------------------------------------------------------
f=open(‘sp‘)
# l1=[i.strip() for i in f]
l1=(i.strip() for i in f) <------------------ 可叠代對象;
print(next(l1))
a=list(l1) <------------- list() 括號可以包含可叠代對象 ,生成列表;
g=l=(‘egg%s‘%i for i in range(100)) 元組 ---生成器;
print(g)
print(next(g))
>>> i=(‘egg %s‘%i for i in range(100) if i<50)
>>> print(i)
<generator object <genexpr> at 0x7ff0e56b7f10>
>>> print(next(i))
egg 0
>>>
-----------------------------------------------------------------------
列表表達式;
go=os.walk(‘/home/zjf‘)
l1=[‘%s/%s‘%(i[0],j) for i in g for j in i[-1]]
print(l1)
i=[‘egg %s‘%i for i in range(100) if i > 50]
l=[1,2,3,4]
s=‘hello‘
l1=[(num,s1) for num in l for s1 in s]
print(l1)
------------------------------------------------------------------------------------
面向過程函數示例:
import os
def init(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs) #!!!!!!!!!!!!!!!!!! 忘記加參數
next(res)
return res
return wrapper #!!!!!!!!!!!!!!!!!!!!!!忘記返回wrapper
@init
def search(target):
while True:
dir_name = yield
g = os.walk(dir_name)
for i in g:
for j in i[-1]:
file_path = ‘%s/%s‘%(i[0],j)
target.send(file_path)
@init
def opener(target):
‘打開文件獲取文件句柄‘
while True:
file_path=yield
with open(file_path) as f:
target.send((file_path,f)) #!!!!!!!!!!!!!! 傳2個參數
@init
def cat(target):
‘讀取文件內容‘
while True:
file_path,f=yield #!!!!!!!!!!!!!!!!!!!!!接收2個參數
for line in f:
target.send((file_path,line))
@init
def grep(pattern,target): #!!!!!!!!!!!!!!! 先參數,後函數target
‘過濾行內容有無python‘
while True:
file_path,line=yield
if pattern in line:
target.send(file_path)
@init
def printer():
‘打印文件路徑‘
while True:
file_path=yield
print(file_path)
g=search(opener(cat(grep(‘python‘,printer()))))
g.send(‘/home/zjf/geon‘)
協程函數:
----------------------------------------------------------------------------------
示例:作業: 連續輸入網址打印結果;
from urllib.request import urlopen
def get():
while True:
url=yield
res=urlopen(url).read()
print(res)
e=get()
next(e)
print(e.send(‘http://www.baidu.com‘))
print(e.send(‘http://www.sina.com‘))
----------------------------------------------------------------------------------
協程函數:(使用yield 表達式的生成器)
yield 表達式:
開始的生成器不能使用send,
必須先netx()之後才能使用send()
#e.send與next(e) 的區別:
1、如果函數內yield是表達式形式,那麽必須先next(e)
2、二者共同之處都是可以讓函數在上次暫停的位置繼續運行;
不一樣:send在觸發下一次代碼的執行時,會順便給yield賦值;
示例1、:剛蛋吃包子
def eater(name):
print(‘%s start to eat‘%name)
while True:
food=yield #類比: 去飯館點菜以後等著。 print(‘%s start to eat‘%name)
while True:
food=yield #類比: 去飯館點菜以後等著。
print(‘%s get %s,to start eat‘%(name,food))
print(‘done‘)
e=eater(‘剛蛋‘)
print(e)
print(next(e))
e.send(‘包子‘)
print(‘%s get %s,to start eat‘%(name,food))
print(‘done‘)
e=eater(‘剛蛋‘)
print(e)
print(next(e))
e.send(‘包子‘) #send(self,value) yield = ‘包子‘ send 相當於next()
示例2:
def eater(name):
print(‘%s start to eat‘%name)
foodlist=[]
while True:
food=yield foodlist
print(‘%s get %s,to start eat‘%(name,food))
foodlist.append(food)
print(‘done‘)
e=eater(‘剛蛋‘)
# print(e)
print(next(e))
print(e.send(‘包子‘))
示例3: 跳過 next(e)
def fst(fun):
def wrapper(*args,**kwargs):
# fun(**args)
res=fun(*args,**kwargs)
next(res)
return res
return wrapper
@fst # ester=fst(eater)
def eater(name):
print(‘%s start to eat‘%name)
foodlist=[‘動骨‘]
while True:
food=yield foodlist
# print(‘get %s,to start eat‘%food)
foodlist.append(food)
print(‘done‘)
e=eater(‘剛蛋‘) #wrapper(‘剛帶‘)
# print(next(e))
print(e.send(‘包子‘))
print(e.send(‘包子2‘))
print(e.send(‘包子3‘))
print(e.send(‘包子4‘))
print(e.send(‘包子5‘))
print(e.send(‘包子6‘))
----------------------------------------------------------------------------------
示例2、:tail管道 程序用python編寫; tail |grep ‘error‘
import time
def tail(file_path):
with open(file_path,‘r‘) as f:
f.seek(0,2)
while True:
line=f.readline()
if not line:
time.sleep(0.3)
continue
else:
yield line
def grep2(pattern,lines):
for line in lines:
if pattern in line:
print(line)
#調用
g=tail(‘/tmp/a.txt‘) #帶參數的函數作為 另一個函數的輸入!!!
grep2(‘error‘,g)
示例1、:tail程序用python編寫;
#/usr/bin
import time
def tail(file_path):
with open(file_path,‘r‘) as f:
f.seek(0,2)
while True:
line=f.readline()
if not line:
time.sleep(0.3)
continue
else:
print(line,end=‘‘)
tail(‘/tmp/a.txt‘)
------------------------------------------------------------------------------------------
生成器
與return區別:
生成器就是一個函數,這個函數內包含yield這個關鍵字; <-------------------------!!!!!
return只能返回一次,函數徹底結束;多個yield能返回多次值;
生成器的本質就是叠代器; <----------------------------------!!!!!!!!!!!
可叠代的數據類型: 可以用for循環的 就是可叠代的; <-----------------------!!!!!!!!!!
yield幹了什麽:
1、把函數變成生成器---> 叠代器 g=test() g.__iter() g.__next()
#用RETURN 返回值只能返回一次,而YIELD返回多次
#函數在暫停以及下一次繼續喜下一次運行的狀態是有YIELD保存;
yield功能總結;
1、相當於把__iter__和__next__方法封裝到函數內部
2、與RETURN比,RETUN只能返回一次,而YIELD返回多次;
3、函數暫停已繼續運行的狀態通過yield保存
for i in g:
print(i)
示例:
def a(n):
print(‘cut down:‘)
while n > 0:
yield n
n -=1
g=a(5)
#for i in g:
for i in g:
print(i)
示例:
def a(n):
print(‘cut down:‘)
while n > 0:
yield n
n -=1
g=a(5)
#for i in g:
# print(i)
或者:
while True:
try:
print(next(g))
except StopIteration:
break
--------------------------------------------------------------------------------
def test():
print(‘first‘)
yield 1 #return 1 碰到yield 停止,並返回 1
yield 2
test()
g=gest()
print(isinstance(g,Iterator)) 是否是可叠代對象;
print(next(g)) 觸發對象是函數;
示例:
def scq():
print(‘a‘)
yield 1,2,3,4
print(‘b‘)
yield 2
print(‘c‘)
yield 3
res_sc=scq()
res=next(res_sc)
print(res)
res=next(res_sc)
print(res)
res=next(res_sc)
----------------------------------------------------------------------------------
isinstance(‘ssssss‘,str)
type(‘ssss‘) is str >>>>>>>>> True
可叠代的數據類型: 可以用for循環的 就是可叠代的;
數據類型是叠代器: 只有文件本身是叠代器;
叠代器 (優缺點)
1、 提供了一種不依賴索引取值的方式;這樣就可以遍歷沒有索引的可叠代對象:
如: 字典,集合,文件
2、 叠代器與列表比較,叠代器更省內存;(惰性計算;)
3、 缺點:無法獲取叠代器長度;使用不如列表索引取值靈活;
叠代器一次性取值;
d={‘a‘:1,‘b‘:2,‘c‘:3}
i=iter(d)
while True:
try:
print(next(i))
except StopIteration: # 類似if StopIteration:
break
#可叠代的: 只要對象本身有__iter__()方法,那它就是可叠代的;
d={‘a‘:1,‘b‘:2,‘c‘:3}
i=d.__iter__()
print(i.__next__())
______________________________________________________________________________
把裝飾器內的參數包到函數裏面; @timmer(auth_type=file) 有參裝飾器!
示例:
裝飾器: 最重要的是定義wrapper不能少了return值;!!!!!!!!!!!!!!!!!!
def auth2(auth_type):
def auth(fun):
print(auth_type)
def wrapper(*args,**kwargs):
if auth_type==‘file‘:
name=input(‘username:‘)
password=input(‘password:‘)
if name==‘zhejiangf4‘ and password==‘sb‘:
print(‘auth successful‘)
res=fun(*args,**kwargs)
return res
else:
print(‘auth error‘)
return wrapper
return auth
@auth2(auth_type=‘file‘)
def index():
print(‘welcome to index page !‘)
index()
補充:
@ccchttps://www.baidu.com/
@bbb
@aaa
def fun():
print(‘aaa‘)
fun=ccc(bbb(aaa(fun)))
示例3:
@ccc(‘c‘)
@bbb(‘b‘)
@aaa(‘a‘)
def func():
pass
func=ccc(‘c‘)(bbb(‘b‘)(aaa(‘a‘)(func)))
______________________________________________________________________________
#裝飾器
import time
def timmer(fun):
def wrapper():
start_time=time.time()
func() -------------->index()
stop_time=time.time()
s_time=stop_time-start_time
print(‘pro runs time is %s‘%s_time)
return wrapper
@裝飾器語法 timmer名稱
@timmer #--------> index=timmer(inex)=wrapper !!!!!!!!!!!!註意:是index名字!
def index():
time.sleep(3)
print(‘welcme to old boy‘)
index() index=wrapper -------------------wrapper()
執行過程:----------1、先找到index ---index地址,2、執行 ()
______________________________________________________________________________
閉包:首先必須是內部定義的函數,包含對外部作用域,而非全局作用域名字的引用;
x=1
def f1():
x=2
def f2():
print(x)
return f2 # f2!
f=f1() # --->內部f2
f()
print(f.__closure__) # 閉包有__closure__
print(f.__clousure__[0].cell_contents)
例子2:
x=1
def f1(x):
# x=2
def f2():
print(x)
return f2
f=f1(1000000000)
f()
print(f.__closure__)
print(f.__closure__[0].cell_contents)
[email protected]:~/test$ python3 a.py
1000000000
(<cell at 0x7f9158116468: int object at 0x7f915811e710>,)
1000000000
例子3:
from urllib.request import urlopen
def get(url):
def index():
return urlopen(url).read()
return inex
f=get(‘http://www.baidu.com‘)
print(f.__closure__[0].cell_contents)
# 下載www.baidu頁面
______________________________________________________________________________
功能(def),主邏輯(if ....);---------
函數可以看成變量:函數可以被賦值;可以被當作參數傳遞;
def foo():
print(‘foo‘)
def bar(func):
print(func) #打印 foo 內存地址;
fun() #執行 foo 函數;
bar(foo)
_______________________________________________________________________________
x=1
def foo():
x=1
print(x)
foo()
作用域: 函數內部---->函數外部-----> 內置名稱
_______________________________________________________________________________
參數位置順序: (x,*args,**kwargs)
**kwargs 字典方式; 除位置參數意外剩下的。
eg:
def foo(x,*args,**kwargs):
print(x)
print(args)
print(kwargs)
foo(1,y=1,z=2) y=1,z=2 傳給kwargs
>>> foo(3,‘a‘=2)
File "<stdin>", line 1
SyntaxError: keyword can‘t be an expression
def foo(x,**kwargs):
print(x)
print(kwargs)
foo(1,y=2,a=3,b=4) # **kwagrs實參索引不能加 ‘‘ !!!!!!!!!!!!!!
>>>>>>1
>>>>>>{‘y‘:2,‘a‘:3,‘b‘:4}
__________________________________________________________________________________
*args #args 位置參數;
示例1:
def foo(x,*args):
print(x)
print(args)
foo(1,2,3,4,5,6,‘a‘,‘b‘) *args 實參元組格式必須加 ‘‘
示例2:
def bar(x,y,z): #需要一一對應;(與*(值))
print(x)
print(y)
print(z)
bar(*(1,2,3)) # *(1,2,3) 類似1,2,3 = bar(1,2,3)
多出的以元組的形式給args
sum([1,2,3,4])
tips:
1、位置參數特點: 必須傳值的參數!
2、默認參數必須放在位置參數後面!
3、是參是可變類型 結果會受函數的影響 (編程可控性變差): 不可變類型不會;
def bar(x):
x.append(4)
x=[1,2,3,]
bar(x) # x傳遞的是內存地址;
print(x)
>>>>>[1,2,3,4]
__________________________________________________________________________________
head,*_=[1,2,3,4,5]
>>>head
>>>1 對於元組,序列類型都可以這麽玩;
a,b,c,d,e=[1,2,3,4,5]
a,_,_,_,e=[1,2,3,4,5]
>>>a
>>>1
>>>e
>>>5
x=‘hello‘
x,y,z,x1,x2=‘hello‘
x=‘h‘
y=‘e‘
z=‘l‘
x1=‘l‘
x2=‘9‘
例子1:
def bar(x,y):
return 1,2,3 # 多值return
a,b,c=bar(1,2)
print(a)
print(b)
print(c)
例子2:
def foo(x,y):
print(x)
print(y)
a=100
b=200
foo(a,b) #是參必須是明確的值
例子3:
x=[] #每次改全局的值;
def register(name,name_list=x):
name_list.append(name)
register(‘ASB‘)
register(‘ysb‘)
__________________________________________________________________________________
def bar(x,y):return 1,2,3,4,[1,2],{‘a‘,1}
多值返回,格式為元組;
>>>>(1, 2, 3, 4, [1, 2], {1, ‘a‘})
_______________________________________________
def bar(x,y):
res=x+y
return res
res1=bar(1,2)
res=bar(1,2)*10
bar(bar(1,2),3)
def 函數名(arg1,arg2,arg3):
‘描述信息‘
函數體
return 1 (可以是任意數據類型;)
無參函數一般不需要返回值;
____________________________________________________________________________________
硬盤保存數據--------->(完全讀到內存;) 其實就是覆蓋原來的數據;
with open(‘a.txt‘) as f, open(‘b.txt‘) as f2:
pass
f.seek(0) 光標到開頭,truncate(3) 從開頭截斷到第3個位置;其他丟棄;
truncate(3)
with open(‘a.txt‘,‘w‘) as f:
f.writelines([‘111111111\n‘,‘22222222222\n‘)
f.seek(0)
f.truncate(3)
with open(‘a.txt‘,‘w‘) as f:
f.writelines([‘111111111\n‘,‘22222222222\n‘)
eval() 字符串轉字典,列表;
函數部分