函數是指將一組語句的集合經過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名便可python
特性:算法
1.定義函數
def 函數名(參數): ... 函數體 ... 返回值
函數的定義主要有以下要點:spa
2.參數設計
函數的有三種不一樣的參數:code
普通參數htm
#定義函數 #n是函數name的形式參數,簡稱:形參 def name(n): print(n) # jack #執行函數 #'jack'是函數name的實際參數,簡稱:實參 name('jack')
默認參數對象
def func(name, age = 18): print("%s:%s"%(name,age)) # 指定參數 func('jack', 19) # 上面輸出jack:19 # 使用默認參數 func('jack') # 上面輸出jack:18 注:默認參數須要放在參數列表最後
動態參數(*args) blog
def func(*args): print(args) # 執行方式一 func(11,22,33,55,66) # 上面輸出(11, 22, 33, 55, 66) # 執行方式二 li = [11,22,33,55,66] # 上面輸出(11, 22, 33, 55, 66) func(*li)
動態參數(**kwargs) 遞歸
def func(**kwargs): print(kwargs) # 執行方式一 func(name='jack',age=18) # 上面輸出{'name': 'jack', 'age': 18} # 執行方式二 li = {'name':'jack', 'age':18, 'job':'pythoner'} func(**li) # 上面輸出{'name': 'jack', 'age': 18, 'job': 'pythoner'}
參數順序:位置參數、默認參數(即關鍵字參數,形參中若是默認參數後面有可變位置參數,實參中,這個默認參數不能寫成關鍵字參數樣式,只能寫一個值,即位置參數的樣子)、可變位置參數、可變關鍵字參數。
def hi(a,*args,**kwargs): print(a,type(a)) # 11 <class 'int'> print(args,type(args)) # (22, 33) <class 'tuple'> print(kwargs,type(kwargs)) # {'k1': 'jack', 'k2': 'tom'} <class 'dict'> hi(11,22,33,k1='jack',k2='tom')
3.返回值
函數外部的代碼要想獲取函數的執行結果,就能夠在函數裏用return語句把結果返回。
def stu_register(name, age, course='python' ,country='CN'): print("----註冊學生信息------") print("姓名:", name) print("age:", age) print("國籍:", country) print("課程:", course) if age > 22: return False else: return True registriation_status = stu_register("老王",22,course="PY全棧開發",country='JP') if registriation_status: print("註冊成功") else: print("too old to be a student.")
注意:
4.全局、局部變量
在函數中定義的變量稱爲局部變量,在程序的一開始定義的變量稱爲全局變量。
全局變量做用域是整個程序,局部變量做用域是定義該變量的函數。
當全局變量與局部變量同名時,在定義局部變量的函數內,局部變量起做用;在其它地方全局變量起做用。
全局變量在函數裏能夠隨便調用,但要修改就必須用 global 聲明
# 全局變量 P = 'jack' def name(): global P # 聲明修改全局變量 P = 'jenny' # 局部變量 print(P) # jenny def name2(): print(P) # jenny name() name2() # jenny
Python的內置函數有許多,以下圖:
# 匿名函數,冒號前面是形參,冒號後面是函數體,並將結果return到函數調用處 f = lambda a, b: a + b print(f(2, 3)) # 5 # abs() 取絕對值 print(abs(-111)) # 111 # all() 循環可迭代對象的每一個元素,都爲真則返回True,不然返回假 # 0,None ,"",[],(),{} 是假的 print(all([11, 22])) # True # any 有一個爲真,所有都爲真 print(any([0, 0, None])) # False # bin 將十進制轉換成2進制 # oct() hex() print(bin(11)) # 0b1011 # chr() 找到數字對應的ascii碼 # ord() ascii碼對應的數字 # chr ord 只適用於ascii碼 print(chr(65)) # A print(ord('A')) # 65 # divmod 返回除法的(值,餘數) print(divmod(10, 3)) # (3,1) # eval 計算器的功能 返回結果 print(eval('a+60', {'a': 90})) # 150 # exec,執行python代碼,沒有返回值 exec("for i in range(5):print(i)") # 直接循環輸出0,1,2,3,4 # filter(函數,可迭代的對象) # 循環能夠迭代的對象,傳入函數中執行,若是不符合就過濾 def fun(s): # 定義判斷一個數是不是偶數的函數 if s % 2 == 0: return True else: return False ret = filter(fun, [1, 2, 3, 4, 5, 6, 7, 8]) for i in ret: print(i) # 打印出2,4,6,8 # 用匿名函數改寫一下 ret1 = filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5, 6, 7, 8]) for i in ret1: print(i) # 2,4,6,8 # map將傳入的函數依次做用到序列的每一個元素,並把結果做爲新的Iterator返回 ret = map(lambda x: x + 100, [1, 2, 3]) for i in ret: print(i) # 101,102,103 # globals() 獲取當前文件的全部全局變量 # locals() 獲取當前文件的全部局部變量 # hash() 獲取哈希值 # isinstance 看某個對象是否是某個類建立的 # iter() 建立一個能夠被迭代的對象 next()取下一個值 k = iter([1, 2, 3, 4]) print(next(k)) # 1 # pow() 求指數 print(pow(2, 10)) # 1024 # round() 四捨五入 # zip l1 = [1, 2, 3, 4] l2 = ['a', 'b', 'c', 'd'] k = zip(l1, l2) for i in k: print(i) # 打印出(1,a),(2,b).... a = [1, 2, 3, 4, 5] b = ['aaa', 'bbb', 'ccc', 'ddd'] c = [111, 222, 333, 444] for i in zip(a, b, c): print(i) # (1, 'aaa', 111) # (2, 'bbb', 222) # (3, 'ccc', 333) # (4, 'ddd', 444) for i, j, k in zip(a, b, c): print(i, j, k) # 1 aaa 111 # 2 bbb 222 # 3 ccc 333 # 4 ddd 444 # zip應用 for m, n in zip(title_list, content_list): # 把標題和圖片對個對應 print('正在下載>>>>>:' + m, n)
用遞歸寫一個階乘函數 f(n)算出n的階乘
def f(n): if n==0: # n=0的話直接返回空,對用戶輸入的零進行判斷 return None elif 1==n: # n=1的話就再也不遞歸 return n else: return n*f(n-1) # 遞歸在執行f(n-1) 直到f(1) print(f(5)) # 120 ''' f(5)的執行過程以下 ===> f(5) ===> 5 * f(4) ===> 5 * (4 * f(3)) ===> 5 * (4 * (3 * f(2))) ===> 5 * (4 * (3 * (2 * f(1)))) ===> 5 * (4 * (3 * (2 * 1))) ===> 5 * (4 * (3 * 2)) ===> 5 * (4 * 6) ===> 5 * 24 ===> 120 '''
利用函數編寫以下數列:
斐波那契數列指的是這樣一個數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368...
用遞歸獲取斐波那契數列中的第10個數
def fun(n): # fun(10)便可計算第十個斐波拉數 if 1==n : # 直接定義前面兩個數爲 0 ,1,若是輸入的n爲1,2的話直接就返回了 return 0 elif 2==n: return 1 else: return fun(n-1)+fun(n-2) #若是輸入的不是1,2則進行遞歸出來計算他前面兩個數的和 ''' fun(5)的執行過程以下(fun(10)的結果爲34) ===> fun(5) ===> fun(4)+fun(3) ===> fun(3)+fun(2) + fun(2)+fun(1) ===> fun(2)+fun(1)+fun(2)+fun(2)+fun(1) ===> 1+0+1+1+1+0 ===> 3 '''
本質是函數,裝飾其它函數,爲其它函數添加附加功能,原則:
裝飾器對被裝飾的函數是透明的,即:被裝飾的函數感知不到裝飾器的存在,由於沒改函數的代碼,運行方式也沒變
裝飾器執行順序
def login(func): # 1,3 def inner(arg): # 4,7 print('yanzheng') # 8 func(arg) # 9 return inner # 5 @login # 2,10 def tv(name): print('welcom %s' %name) # 11 tv('wgy') # 6
統計函數執行時間
import time def timmer(func): def warpper(*args, **kwargs): start_time = time.time() func() stop_time = time.time() print('the func run time is %s' %(stop_time-start_time)) return warpper @timmer def test1(): time.sleep(1) print('in the test1') test1()
經過列表生成式,咱們能夠直接建立一個列表。可是,受到內存限制,列表容量確定是有限的。並且,建立一個包含100萬個元素的列表,不只佔用很大的存儲空間,若是咱們僅僅須要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。因此,若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷推算出後續的元素呢?這樣就沒必要建立完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。要建立一個generator,有不少種方法。
第一種方法很簡單,只要把一個列表生成式的[]
改爲(),
就建立了一個generator:
b = (i*2 for i in range(3)) # 列表生成式的[]改成(),就變成了生成器 print(b) for i in b: print(i)
''' <generator object <genexpr> at 0x00000000021DE8E0> 0 2 4 '''
經過函數寫生成器
函數中加yield(暫停),表示能夠將函數變成生成器,調用函數時獲得一個生成器,yield以後的代碼不執行,yield就返回生成器地址,next調用生成器,能夠像return同樣,返回值,可是不會像return返回一次函數就終止了,並且是在執行過程當中,能夠屢次將數據或者狀態返回到next調用處(能夠返回函數循環體中每次產生的值),如,讀取一個大文件,一邊讀一邊返回。此時腳本中的return信息只在拋出異常的時候打印。
def fib(max): n, a, b = 0, 0, 1 while n < max: print('before yield') # print(b) yield b # 把函數的執行過程凍結在這一步,而且把b的值返回給外面的next() a, b = b, a + b n = n + 1 return 'done' f = fib(3) # 調用函數,將函數變成一個生成器,將地址返回給f print(f) print(f.__next__()) print(next(f)) print(f.__next__()) print(next(f))
''' <generator object fib at 0x0000000001E7E8E0> before yield 1 before yield 1 before yield 2 Traceback (most recent call last): File "F:/test.py", line 15, in <module> print(next(f)) StopIteration: done '''
迭代器
能夠直接做用於for循環的數據類型有如下幾種:
能夠被next()函數調用並不斷返回下一個值的對象稱爲迭代器:Iterator。
注意區別:
可迭代對象:Iterable(能夠直接做用於for循環)
迭代器:Iterator(能夠被next()函數調用並不斷返回下一個值)
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。把list、dict、str等Iterable變成Iterator可使用iter()函數
from collections import Iterator a = [1,2,3] b = iter(a) print(isinstance(b,Iterator)) print(b.__next__()) print(b.__next__()) print(b.__next__()) print(b.__next__()) ''' True 1 2 3 Traceback (most recent call last): File "F:/test.py", line 8, in <module> print(b.__next__()) StopIteration '''
1.寫一個range功能的生成器