5Python集合容器
數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu) 一般將數(shù)據(jù)結(jié)構(gòu)分為兩大類: 線性數(shù)據(jù)結(jié)構(gòu)和非線性數(shù)據(jù)結(jié)構(gòu)。?
線性數(shù)據(jù)結(jié)構(gòu)有: 線性表、棧、隊列、串、數(shù)組和文件; 非線性數(shù)據(jù)結(jié)構(gòu)有: 散列表、樹和圖。
線性表:線性表的邏輯結(jié)構(gòu)是n個數(shù)據(jù)元素的有限序列:(a1, a2 ,a3,…an)n為線性表的長度(n≥0),n=0的表稱為空表。數(shù)據(jù)元素呈線性關(guān)系。必存在唯一的稱為“第一個”的數(shù)據(jù)元素;必存在唯一的稱為“最后一個”的數(shù)據(jù)元素;除第一個元素外,每個元素都有且只有一個前驅(qū)元素; 除最后一個元素外,每個元素都有且只有一個后繼元素。所有數(shù)據(jù)元素在同一個線性表中必須是相同的數(shù)據(jù)類型。2/48線性表按其存儲結(jié)構(gòu)可分為順序表和鏈表。用順序存儲結(jié)構(gòu)存儲的線性表稱為順序表;用鏈?zhǔn)酱鎯Y(jié)構(gòu)存儲的線性表稱為鏈表。將線性表中的數(shù)據(jù)元素依次存放在某個存儲區(qū)域中,所形成的表稱為順序表。一維數(shù)組就是用順序方式存儲的線性表。鏈表(數(shù)據(jù)經(jīng)常插入刪除用鏈表)棧(Stack)也是一種特殊的線性表,是一種后進(jìn)先出(LIFO)的結(jié)構(gòu)。棧是限定僅在表尾進(jìn)行插入和刪除運(yùn)算的線性表,表尾稱為棧頂(top),表頭稱為棧底(bottom)。棧的物理存儲可以用順序存儲結(jié)構(gòu),也可以用鏈?zhǔn)酱鎯Y(jié)構(gòu)。3/48隊列(Queue) 是限定所有的插入只能在表的一端進(jìn)行,而所有的刪除都在表的另一端進(jìn)行的線性表。表中允許插入的一端稱為隊尾(Rear),允許刪除的一端稱為隊頭(Front)。隊列的操作是按先進(jìn)先出(FIFO)的原則進(jìn)行的。隊列的物理存儲可以用順序存儲結(jié)構(gòu),也可以用鏈?zhǔn)酱鎯Y(jié)構(gòu)。散列表又稱為哈希表。散列表算法的基本思想是:4/48以結(jié)點(diǎn)的關(guān)鍵字為自變量,通過一定的函數(shù)關(guān)系(散列函數(shù))計算出對應(yīng)的函數(shù)值,以這個值作為該結(jié)點(diǎn)存儲在散列表中的地址。當(dāng)散列表中的元素存放太滿,就必須進(jìn)行再散列,將產(chǎn)生一個新的散列表,所有元素存放到新的散列表中,原先的散列表將被刪除。在C#語言中,通過負(fù)載因子(loadfactor)來決定何時對散列表進(jìn)行再散列。例如:如果負(fù)載因子是0.75,當(dāng)散列表中已經(jīng)有75%的位置已經(jīng)放滿,那 么將進(jìn)行再散列。負(fù)載因子越高(越接近1.0),內(nèi)存的使用效率越高,元素的尋找時間越長。負(fù)載因子越低(越接近0.0),元素的尋找時 間越短,內(nèi)存浪費(fèi)越多。列表List1. Python內(nèi)置的一種數(shù)據(jù)類型是列表:list。2. list是一種有序的集合,可以隨時添加和刪除其中的元5/48素。3. 序列中的每個元素都分配一個數(shù)字 - 它的位置,或索引,第一個索引是0,第二個索引是1,依此類推。4. 列表可以存放各種類型的數(shù)據(jù)定義列表 語法: 變量名=[值1,值2,值3...值n]name=["唐僧","豬八戒","孫悟空","沙僧"]列表-查 值 = 列表[index] 根據(jù)索引下標(biāo)查找值 index = 列表.index(值) 從列表中找出某個值第一個匹配項的索引位置 count = 列表.count(值) 統(tǒng)計某個元素在列表中出現(xiàn)的次數(shù) lenth = len(列表) 查詢列表的長度,元素的個數(shù) max(列表) ,min(列表) 查詢列表中的最大值,最小值列表-增 列表.append(值) 新增到末尾 列表.insert(下標(biāo),值) 6/48 插入到指定位置 列表.extend(列表) 列表末尾一次性追加另一個序列中的多個值(用新列表擴(kuò)展原來的列表)。列表-改 列表[下標(biāo)] = 值 根據(jù)下標(biāo)修改其值列表-刪 列表.pop() 刪除末尾元素,并返回此元素 列表.pop(下標(biāo)) 根據(jù)元素下標(biāo)刪除,并返回次元素 del 列表[下標(biāo)] 根據(jù)元素下標(biāo)刪除 列表.remove(值) 根據(jù)元素的值刪除列表-判斷 in(存在) 如果存在那么結(jié)果為True,否則為False not in(不存在) 如果不存在那么結(jié)果為True,否則False列表-運(yùn)算符 + * + 和 * 的操作符與字符串相似。 + 號用于組合列表,* 號用于重復(fù)列表。 7/48列表-排序 列表.reverse() 反向列表中元素 列表.sort() 對原列表進(jìn)行排序,如果指定參數(shù),則使用比較 函數(shù)指定的比較函數(shù)列表-切片 列表[num1:num2:num3] num1,num2都是列表的下標(biāo)num3是間隔返回一個新的列表列表-遍歷 使用while循環(huán)遍歷 使用for循環(huán)遍歷元組TuplePython的元組與列表類似,不同之處在于元組的元素不能 修改。元組使用小括號,列表使用方括號。元組的功能 = 列表不修改的功能元組和列表轉(zhuǎn)化列表和元組相互轉(zhuǎn)換8/48 列表 = list(元組) 元組轉(zhuǎn)列表 元組 = tuple(列表) 列表轉(zhuǎn)元組 注意:這兩個方法都是得到一個新的,不會修改原來的字典DictPython內(nèi)置了字典:dict的支持,dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)存儲, 具有極快的查找速度。定義字典 格式: 字典 = {key1 : value1, key2 : value2 ......} 鍵必須是唯一的,但值則不必。 值可以取任何數(shù)據(jù)類型,如字符串,數(shù)字或元9/48組。 dict內(nèi)部存放的順序和key放入的順序是沒有關(guān)系的。字典-增/改 字典[鍵] = 值 如果次key不存在,就是往字典里新增一個鍵值對; 否則,就是修改由于一個key只能對應(yīng)一個value, 所以,多次對一個key放入value,后面的值會把 前面的值沖掉字典-刪 1.字典.pop(鍵) 根據(jù)鍵,刪除指定的值,并將此值返回 2.del 字典[鍵] 根據(jù)鍵,刪除指定的值 3.字典.popitem() 隨機(jī)刪除一個 4.字典.clear() 清空字典里的鍵值對字典-查 值 = 字典[鍵] 根據(jù)鍵查詢值 字典.get(鍵,[默認(rèn)值]) 通過dict提供的get方法,如果key不存在,可以返回None,或者自己指定的值 len(字典)10/48 計算字典元素個數(shù),即鍵的總數(shù)。 str(字典) 輸出字典可打印的字符串表示。 dict.keys() 以列表返回一個字典所有的鍵 dict.values() 以列表返回一個字典所有的值 dict.items() 以列表返回可遍歷的(鍵, 值) 元組數(shù)組字典-判斷 鍵 in 字典 如果鍵在字典中存在,返回True否則,返回False字典-遍歷 使用for循環(huán)遍歷的三種方式: for key in dict: print('%s:%s'%(key,dict[key]))for key in dict.keys(): print('%s:%s'%(key,dict[key]))for k,v in dict.items(): print('%s:%s'%(k,v)字典-其他方法 dict.copy() 返回一個新的字典,內(nèi)容一樣,地址不同 dict.fromkeys(seq[, val])) 創(chuàng)建一個新字典,以序列 seq 中元素做字典的鍵,val 為字典所有鍵對應(yīng)的初始值 dict.setdefault(key, default=None) 和get()類似, 但如果鍵不存在于字典中,將會添加鍵并將值設(shè)為default如果鍵在字典中,返回這個鍵所對應(yīng)的值。如果鍵不在字典中,向字典中插入這個鍵,并且以default為這個鍵的值,并返回 default。default的默認(rèn)值為None11/48 dict.update(dict2) 把字典dict2的鍵/值對更新到dict里字典與列表對比 和list比較,dict有以下幾個特點(diǎn): 查找速度極快,不會隨著key的增加而變慢; 需要占用大量的內(nèi)存,內(nèi)存浪費(fèi)多。 而list: 查找和插入的時間隨著元素的增加而增加; 占用空間小,浪費(fèi)內(nèi)存很少。 所以,dict是用空間來換取時間的一種方法。Set集合set集合是一個無序,不能重復(fù)的集合容器,所以可以用來過濾重復(fù)元素。定義Set集合 語法: 變量名 = {值1,值2,值3.......}names={"張三","李四","王五","趙六 12/48Set集合-增 set.add(值) 添加元素 set.update(值) 將一個可迭代的內(nèi)容,一一加入Set集合-刪 set.remove(值) 移除指定的值 如果移除的值不存在 會報錯 set.discard(值) 移除指定的值 如果移除的值不存在 也不會報錯 set.pop() 隨機(jī)刪除一個元素 set.clear() 移除set中的所有的元素Set集合-其他操作 | 并集 & 交集 intersection 交集 - 差集 difference 差集 in 判斷 union 聯(lián)合 issubset 子集 issuperset 父集 13/48總結(jié)數(shù)據(jù)結(jié)構(gòu)列表的使用元組的不可變性列表和元素相互轉(zhuǎn)換字典鍵值對set值唯一本章作業(yè)1.兩個列表進(jìn)行合并操作2.使用列表判斷一個列表是否在另外一個列表中3.列表的反轉(zhuǎn)4.列表的排序14/485.實(shí)現(xiàn)對列表的增刪改查功能6.如何將0-10隨機(jī)存入列表中7.求出元組(90,34,-23,18,12)中的最大值和最小值8. 針對列表[90,34,-23,18,12]從小到大進(jìn)行排序,然后 輸出排序后結(jié)果9. 編程輸出所有的三位水仙花數(shù) 水仙花數(shù):各位數(shù)字的立方數(shù)相加等于該數(shù)本身 例如 153 1*1*1+5*5*5+3*3*3=153 153就是一個三位水仙花數(shù)10.為哈希表追加不重復(fù)的100個值,且每個值都是1-100之間的隨機(jī)數(shù),問哪個數(shù)字重復(fù)的次數(shù)最多,重復(fù)了多少次?11.假定書籍的種類有5種,設(shè)計何種的數(shù)據(jù)結(jié)構(gòu)可以達(dá)到 快速查詢某類所有書籍的功能(提示:用Dictionary)
思考題:
1.如何實(shí)現(xiàn)一個單向鏈表
2.解析用戶輸入的一個算數(shù)表達(dá)式 算出其結(jié)果(選作)
2-1.沒有括號和負(fù)號(中等難度)
2-2.帶括號和負(fù)號(高難度)
3.如何用隊列實(shí)現(xiàn)約瑟夫環(huán)
約瑟夫環(huán):假設(shè)有n個人坐成一圈,從某個人開始報數(shù),
數(shù)到m的人出圈,接著從出圈的下一個人開始重新報數(shù),
數(shù)到m的人再次出圈,如此反復(fù),直到所有人都出圈,請 列出出圈順序。
6日期時間
時間模塊
15/48
在我們平常的代碼中,經(jīng)常需要和時間打交道。
在Python中,與時間處理相關(guān)的模塊有:
time、datetime以及calendar,這里講解time
模塊模塊的引入:import time
time中常用函數(shù):
time.time()
返回當(dāng)前時間的時間戳(1970紀(jì)元后經(jīng)過的浮
點(diǎn)秒數(shù))。
time.ctime()
獲取當(dāng)前日期時間
time.localtime()
將一個時間戳轉(zhuǎn)換為當(dāng)前時區(qū)的
struct_time,即時間數(shù)組格式的時間
time.sleep(secs)
線程推遲指定的時間運(yùn)行
time.timezone
是當(dāng)?shù)貢r區(qū)(未啟動夏令時)距離格林威治的
偏移秒數(shù)(>0,美洲;<=0大部分歐洲,亞洲,非洲)。
time.tzname
包含一對根據(jù)情況的不同而不同的字符串,分 別是帶夏令時的本地時區(qū)名稱,和不帶的。
time.altzone
返回格林威治西部的夏令時地區(qū)的偏移秒數(shù)。
如果該地區(qū)在格林威治東部會返回負(fù)值(如西歐,包括英
國)。對夏令時啟用地區(qū)才能使用。
time.asctime([tupletime]) 接受時間元組并返
回一個可讀的形式為"Tue Dec 11 18:07:14 2008"(2008
16/48
年12月11日 周二18時07分14秒)的24個字符的字符串。
time.clock( ) 用以浮點(diǎn)數(shù)計算的秒數(shù)返回當(dāng)前
的CPU時間。用來衡量不同程序的耗時,比time.time()更
有用。
time.gmtime([secs]) 接收時間戳(1970紀(jì)元
后經(jīng)過的浮點(diǎn)秒數(shù))并返回格林威治天文時間下的時間元
組t。注:t.tm_isdst始終為0
time.mktime(tupletime) 接受時間元組并返回
時間戳(1970紀(jì)元后經(jīng)過的浮點(diǎn)秒數(shù))。
time.strftime(fmt[,tupletime]) 接收以時間元
組,并返回以可讀字符串表示的當(dāng)?shù)貢r間,格式由fmt決
定。
time.strptime(str,fmt='%a %b %d %H:%M:
%S %Y') 根據(jù)fmt的格式把一個時間字符串解析為時間元
組。
time.tzset() 根據(jù)環(huán)境變量TZ重新初始化時間
相關(guān)設(shè)置。
時間元組:
Python函數(shù)用一個元組裝起來的9組數(shù)字表示時間:
t=(2018,1,2,3,4,5,1,22,0)
17/48
日期格式化
time.strftime(format[, tupletime]):
把一個代表時間的元組或者struct_time(如由
time.localtime()和time.gmtime()返回)轉(zhuǎn)化為格式化的
時間字符串。如果t未指定,將傳入time.localtime()。如果
元組中任何一個元素越界,ValueError的錯誤將會被拋
18/48
出。
19/48
20/48
日期時間模塊
日期時間——datetime
日期模塊的引入:from datetime import datetime
獲取當(dāng)前日期對象
datetime.now()
設(shè)置日期獲取日期對象
datetime(year, month, day [,hour, minute, second])
日期時間字符串的轉(zhuǎn)換
日期時間<==>字符串
日期轉(zhuǎn)換字符串
datetime.strftime(“%Y-%m-%d %H:%M:%S”)
from datetime import datetime
dt=datetime.now()
t=dt.strftime("%Y{y}%m{m}%du0z1t8os %H:%M:%S").format(y="年",m="月",d="日")
print(t)
字符串轉(zhuǎn)換日期
datetime.strptime(“2017-10-01 00:00:00”,“%Y-%m-%s %H:%M:%S”)
日歷模塊
21/48
日歷(Calendar)模塊
此模塊的函數(shù)都是日歷相關(guān)的,例如打印某月的字符月
歷。
星期一是默認(rèn)的每周第一天,星期天是默認(rèn)的最后一天。
更改設(shè)置需調(diào)用calendar.setfirstweekday()函數(shù)。模塊包
含了以下內(nèi)置函數(shù):
calendar.calendar(year,w=2,l=1,c=6)
返回一個多行字符串格式的year年年歷,3個月一行,
間隔距離為c。 每日寬度間隔為w字符。每行長度為21*
W+18+2* C。l是每星期行數(shù)。
calendar.firstweekday( )
返回當(dāng)前每周起始日期的設(shè)置。默認(rèn)情況下,首次載入
caendar模塊時返回0,即星期一。
calendar.isleap(year)
是閏年返回True,否則為false。
calendar.leapdays(y1,y2)
返回在Y1,Y2兩年之間的閏年總數(shù)。
calendar.month(year,month,w=2,l=1)
返回一個多行字符串格式的year年month月日歷,兩行
標(biāo)題,一周一行。每日寬度間隔為w字符。每行的長度為
7* w+6。l是每星期的行數(shù)。
calendar.monthcalendar(year,month)
返回一個整數(shù)的單層嵌套列表。每個子列表裝載代表一
個星期的整數(shù)。Year年month月外的日期都設(shè)為0;范圍內(nèi)
22/48
的日子都由該月第幾日表示,從1開始。
calendar.monthrange(year,month)
返回兩個整數(shù)。第一個是該月的星期幾的日期碼,第二
個是該月的日期碼。日從0(星期一)到6(星期日);月
從1到12。
calendar.prcal(year,w=2,l=1,c=6)
相當(dāng)于 print calendar.calendar(year,w,l,c).
calendar.prmonth(year,month,w=2,l=1)
相當(dāng)于 print calendar.calendar(year,w,l,c)。
calendar.setfirstweekday(weekday)
設(shè)置每周的起始日期碼。0(星期一)到6(星期
日)。
calendar.timegm(tupletime)
和time.gmtime相反:接受一個時間元組形式,返回該
時刻的時間戳(1970紀(jì)元后經(jīng)過的浮點(diǎn)秒數(shù))。
calendar.weekday(year,month,day)
返回給定日期的日期碼。0(星期一)到6(星期日)。
月份為 1(一月) 到 12(12月)。
總結(jié)
時間模塊
日期時間模塊
日期時間字符串的轉(zhuǎn)換
日歷模塊
本章作業(yè)
1.輸入一個日期,格式如:2010 10 24 ,判斷這一天是這
23/48
一年中的第幾天。
2.已知2011年11月11日是星期五,輸入日期 ,問YYYY年
MM月DD日是星期幾
3.系統(tǒng)會隨機(jī)給你一個日期(yyyy-MM-dd)字符串,你需 要計算這個時間上一個月的最后一天的具體日期,最后以
yyyy年MM月dd日的字符形式返回
4.輸入兩個日期,獲得兩個日期相差幾天,幾小時,幾秒
7函數(shù)
掌握方法的聲明、定義,以及參數(shù)和返回值的含義;
函數(shù)的介紹
什么是方法?
廣義:一般是指為獲得某種東西或達(dá)到某種目的而采取的
手段與行為方式。
狹義:方法是指由一系列的程序語句組成的代碼塊
方法(method)也叫函數(shù)(function),就是將一堆代碼 進(jìn)行重用的一種機(jī)制。函數(shù)就是一段代碼,這段代碼可能
有輸入的值(參數(shù)),可能會返回值。一個函數(shù)就像一個
專門做這件事的人,我們調(diào)用它來做一些事情,它可能需
要我們提供一些輸入信息給它,它執(zhí)行完成后可能會有一
些執(zhí)行結(jié)果給我們。要求的輸入的信息就叫參數(shù),返回的
執(zhí)行結(jié)果就是返回值。
str=input("請輸入名字")就是一個有返回結(jié)果的函數(shù);
print("hello")就是一個有執(zhí)行參數(shù)的函數(shù),只有告訴print
被打印的數(shù)據(jù)它才知道如何打?。籹tr2=str.find("a")則是
一個既有參數(shù)又有返回值的函數(shù)。
有了函數(shù)寫代碼就像拼積木,python中的各種各樣的技術(shù)
24/48
其實(shí)就是通過for、if等這些基礎(chǔ)的語法將不同的函數(shù)按照
一定的邏輯組織起來。
方法有什么好處?
重用
無論現(xiàn)實(shí)世界還是程序世界,都以方法來達(dá)到重用的目的
函數(shù)的定義與調(diào)用
定義語法:
def 函數(shù)名([參數(shù)]):
代碼塊
[return 表達(dá)式]
命名規(guī)則:方法名開頭大寫,參數(shù)名開頭小寫,方法名、
參數(shù)名、變量名要有意義;
方法的目的在于重用,所有的方法編寫完成后,都處于等
待調(diào)用狀態(tài),被調(diào)用后方法開始執(zhí)行,直到方法返回(有
無返回值均必須返回)
方法大多數(shù)會在其他方法內(nèi)部被調(diào)用
def FirstMethod():
print("我是一個方法")
FirstMethod()
25/48
多級調(diào)用關(guān)系在程序中表現(xiàn)如下:
===>:調(diào)用
<===:返回
Method1()<===>Method2()<===>Method3
()<===>Method4()
棧:后進(jìn)先出的一種存儲結(jié)構(gòu)
執(zhí)行過程如下:
1.Method1()執(zhí)行到調(diào)用Method2()的調(diào)用點(diǎn)時 方法被阻
塞 Method1()進(jìn)入調(diào)用堆棧
2.Method2()執(zhí)行到調(diào)用Method3()的調(diào)用點(diǎn)時 方法被阻塞 Method2()進(jìn)入調(diào)用堆棧
26/48
3.Method3()執(zhí)行到調(diào)用Method4()的調(diào)用點(diǎn)時 方法被阻塞 Method3()進(jìn)入調(diào)用堆棧
4.Method4()開始執(zhí)行 執(zhí)行完畢后 返回結(jié)果給調(diào)用堆棧
5.調(diào)用堆棧收到返回值后,將棧頂也就是Method3()出棧繼續(xù)執(zhí)行并返回
27/48
6.調(diào)用堆棧收到返回值后,將棧頂也就是Method2()出棧繼續(xù)執(zhí)行并返回
7.調(diào)用堆棧收到返回值后,將棧頂也就是Method1()出棧繼續(xù)執(zhí)行并返回
28/48
8.堆棧為空 本次多級調(diào)用執(zhí)行完畢
注意:所有的方法均需要返回?為什么有的方法沒有return?
無返回值的方法可以將return;省略
形式參數(shù)與實(shí)際參數(shù)
參數(shù)分為兩種:
形式參數(shù):在編寫方法的時候 預(yù)定義的參數(shù)
實(shí)際參數(shù):在實(shí)際調(diào)用(使用)方法的時候 傳入方法的參
數(shù)
參數(shù)的類型:
形式參數(shù):任意的數(shù)據(jù)類型 由方法編寫者在預(yù)定義時限定
實(shí)際參數(shù):任意的數(shù)據(jù)類型(和形式參數(shù)匹配)在方法的
調(diào)用者中定義賦值
簡單示意:
形式參數(shù):
29/48
#radius即為形式參數(shù)
def Area(radius):
return 3.14*radius*radius
實(shí)際參數(shù):
#r即為實(shí)際參數(shù)
r=1
area=Area(r)
print("面積為%s"area)
傳參的實(shí)質(zhì): radius = r;
將實(shí)際參數(shù)傳遞給形式參數(shù)
函數(shù)的返回值
返回值類型:任意的數(shù)據(jù)類型
方法有無返回值取決于方法的調(diào)用者是否需要返回值
1.讀取用戶輸入的整數(shù),如果用戶輸入的是數(shù)字,則返回輸
入的值,否則提示用戶重新輸入。
2.查找兩個整數(shù)中的最大值
3.計算輸入列表所有元素的和:
思考:
寫一個方法,計算一個int類型list中每個元素的總和 、最大
值與最小值?
局部變量與全局變量
30/48
全局變量與局部變量
兩者的本質(zhì)區(qū)別就是在于作用域;
用通俗的話來理解的話,
全局變量是在整個py文件中聲明,全局范圍內(nèi)都可以訪問
局部變量是在某個函數(shù)中聲明的,只能在該函數(shù)中調(diào)用
它,如果試圖在超出范圍的地方調(diào)用,程序就掛掉了
如果在函數(shù)內(nèi)部定義與某個全局變量一樣名稱的局部變
量,就可能會導(dǎo)致意外的效果,可能不是你期望的。因此
不建議這樣使用,這樣會使得程序很不健全
直接來看幾個例子來理解全局變量和局部變量的區(qū)別吧:
def fun(x):
y=2
print("乘法的運(yùn)行結(jié)果:",x*y)
num1=1
print("初始num1=",num1)
fun(num1)
print("y的值是:",y)
報錯的原因是因為試圖訪問局部變量,但是訪問的地方不在該變量y的作用域中
def fun():
num1=2
print("函數(shù)內(nèi)修改后num1=",num1)
num1=1
print("初始num1=",num1)
fun()
print("運(yùn)行完函數(shù)后num1=",num1)
可以看到在函數(shù)內(nèi)部對全局變量的修改后,在函數(shù)執(zhí)行完
畢,修改的結(jié)果是無效的,全局變量并不會受到影響
31/48
global關(guān)鍵字
如果真的想要在函數(shù)體內(nèi)修改全局變量的值,就要使用
global關(guān)鍵字
def fun():
global num1
num1=2
print("函數(shù)內(nèi)修改后num1=",num1)
num1=1
print("初始num1=",num1)
fun()
print("運(yùn)行完函數(shù)后num1=",num1)
使用global關(guān)鍵字就是告訴python編譯器這個變量不是局
部變量而是全局變量,其實(shí)有點(diǎn)像是"引用"的意思
32/48
可選參數(shù)
含義:可選參數(shù),也成為默認(rèn)參數(shù),是指給方法的特定參
數(shù)指定默認(rèn)值,在調(diào)用方法時可以省略掉這些參數(shù)。
注意事項:
(1)可選參數(shù)不能為參數(shù)列表的第1個參數(shù),必須位于所 有的必選參數(shù)之后(除非沒有必選參數(shù));
(2)可選參數(shù)必須指定一個默認(rèn)值,且默認(rèn)值必須是一 個常量表達(dá)式,不能為變量;
(3)所有可選參數(shù)以后的參數(shù)都必須是可選參數(shù)。
(4)若要為可選參數(shù)傳遞新的值 ,注意數(shù)據(jù)類型
示例:
def Add(a,b=2):
result = a + b
return result
a = 10
#省略b實(shí)際參數(shù)的傳遞
Add(a)
#也可以不省略 為b重新賦值
Add(a,5)
命名參數(shù)
命名參數(shù),也可以叫關(guān)鍵字參數(shù)
對于關(guān)鍵字參數(shù),函數(shù)的調(diào)用者可以傳入任意不受限制的
關(guān)鍵字參數(shù)。至于到底傳入了哪些,就需要在函數(shù)內(nèi)部通
過kw檢查。
33/48
注意:如果要限制關(guān)鍵字參數(shù)的名字,就可以用命名關(guān)鍵
字參數(shù)
例:
def person(name, age, *, city="北京", job="程序猿"):
print(name, age, city, job)
person("托尼",15,city="鄭州",job="主播")
可變元組參數(shù)
在Python函數(shù)中,還可以定義可變參數(shù)。顧名思義,可變
參數(shù)就是傳入的參數(shù)個數(shù)是可變的,可以是1個、2個到任
意個,還可以是0個,調(diào)用時可以傳入個數(shù)不同的實(shí)參,具
備很好的靈活性。參數(shù)組裝成一個tuple
參數(shù)數(shù)組必須為參數(shù)列表的最后一個參數(shù)
參數(shù)列表之前可以設(shè)置其他的參數(shù)
示例:
def Add(*tuple):
sum=0
for i in tuple:
sum+=i
return sum
#調(diào)用使用了參數(shù)數(shù)組的方法
Add()
Add(1,3,5)
Add(1,3,5,7)
34/48
可變字典參數(shù)
可變參數(shù)允許你傳入0個或任意個參數(shù),這些可變參數(shù)在
函數(shù)調(diào)用時自動組裝為一個tuple。
而關(guān)鍵字參數(shù)允許你傳入0個或任意個含參數(shù)名的參數(shù),
這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動組裝為一個dict。
例如
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person("蔣昊",18,gender="男")
匿名函數(shù)
匿名函數(shù)
顧名思義就是指:是指一類無需定義標(biāo)識符(函數(shù)名)
的函數(shù)或子程序。
定義
語法格式:lambda 參數(shù):表達(dá)式
lambda語句中,開頭先寫關(guān)鍵字lambda,冒號前是 參數(shù),可以有多個,用逗號隔開;冒號右邊的為表達(dá)式,
需要注意的是只能有一個表達(dá)式。由于lambda返回的是函
數(shù)對象(構(gòu)建的是一個函數(shù)對象),所以需要定義一個變
量去接收。
注意點(diǎn):lambda 函數(shù)可以接收任意多個參數(shù) (包括可選
參數(shù)) 并且返回單個表達(dá)式的值。lambda 函數(shù)不能包含命
35/48
令,包含的表達(dá)式不能超過一個。
匿名函數(shù)優(yōu)點(diǎn):
使用Python寫一些腳本時,使用lambda可以省去定義
函數(shù)的過程,讓代碼更加精簡。
對于一些抽象的,不會被別的地方再重復(fù)使用的函
數(shù),有時候函數(shù)起個名字也是個難題,使用lambda不需要
考慮命名的問題
使用lambda在某些時候然后代碼更容易理解
nums=(1,2,53,6,69)
a=lambda x: max(x)
print(a)
print(type(a))
print(a(nums))
遞歸函數(shù)
遞歸算法的思想
遞歸算法是把問題轉(zhuǎn)化為規(guī)??s小了的同類問題的子問
題。然后遞歸調(diào)用函數(shù)(或過程)來表示問題的解。在C
語言中的運(yùn)行堆棧為他的存在提供了很好的支持,過程一
般是通過函數(shù)或子過程來實(shí)現(xiàn)。
遞歸算法:在函數(shù)或子過程的內(nèi)部,直接或者間接地調(diào)用
自己的算法。
遞歸算法的特點(diǎn):
遞歸算法是一種直接或者間接地調(diào)用自身算法的過程。在
計算機(jī)編寫程序中,遞歸算法對解決一大類問題是十分有
效的,它往往使算法的描述簡潔而且易于理解。
遞歸算法解決問題的特點(diǎn):
36/48
(1) 遞歸就是在過程或函數(shù)里調(diào)用自身。
(2) 在使用遞歸策略時,必須有一個明確的遞歸結(jié)束條 件,稱為遞歸出口。
(3) 遞歸算法解題通常顯得很簡潔,但遞歸算法解題的運(yùn) 行效率較低。所以一般不提倡用遞歸算法設(shè)計程序。
(4) 在遞歸調(diào)用的過程當(dāng)中系統(tǒng)為每一層的返回點(diǎn)、局部
量等開辟了棧來存儲。遞歸次數(shù)過多容易造成棧溢出等。
所以一般不提倡用遞歸算法設(shè)計程序。
遞歸算法的要求
遞歸算法所體現(xiàn)的“重復(fù)”一般有三個要求:
一是每次調(diào)用在規(guī)模上都有所縮小(通常是減半); 二是相鄰兩次重復(fù)之間有緊密的聯(lián)系,前一次要為后一次
做準(zhǔn)備(通常前一次的輸出就作為后一次的輸入); 三是在問題的規(guī)模極小時必須用直接給出解答而不再進(jìn)行
遞歸調(diào)用,因而每次遞歸調(diào)用都是有條件的(以規(guī)模未達(dá)到
直接解答的大小為條件),無條件遞歸調(diào)用將會成為死循環(huán)
而不能正常結(jié)束。
簡單步驟:
1.明確確定方法的功能含義
2.明確方法出口
3.在使用中遇到符合方法功能定義的地方調(diào)用方法
求階乘! n! = n*(n-1)!
f(n) = f(n-1)!*n
5! = 5*4*3*2*1
37/48
def Factorial(num):
print(num)
if num<2:
return num
else:
return Factorial(num-1)*num
print(Factorial(6))
斐波那契數(shù)列
迭代求法1 1 2 3 5 8 13 21 34 55
遞歸深度
獲得深度值:
import sys
sys.getrecursionlimit()
1000
當(dāng)遞歸深度超過這個值的時候,就會引發(fā)這樣的一個異
常。
解決的方式是手工設(shè)置遞歸調(diào)用深度,
方式為
import sys
sys.setrecursionlimit(1000000) #例如這里設(shè)置為一百萬
38/48
總結(jié)
函數(shù)的介紹
函數(shù)的定義和調(diào)用
函數(shù)的4種類型
函數(shù)的參數(shù)
變量作用域
遞歸函數(shù)
匿名函數(shù)
函數(shù)式編程
本章作業(yè)
必做:
1、寫一個方法,在方法內(nèi)依次打印出列表每個元素的
值。
2、寫一個方法,計算列表所有元素的和(注意返回值)。
3、寫一個方法,計算列表所有奇數(shù)下標(biāo)元素的和(注意返
回值)。
4、寫一個方法,計算列表所有偶數(shù)下標(biāo)元素的和(注意返
回值)。
5、寫一個方法可以計算兩個數(shù)的和,想想這個方法有哪
些參數(shù),返回值。
39/48
6、寫一個方法可以計算兩個數(shù)的商(分母不能為0),想想 這個方法有哪些參數(shù),返回值是什么。
7、寫一個方法將傳入的天、小時、分鐘、秒的總和轉(zhuǎn)換
為秒,比如0天、2小時、5分、7秒,他們代表的總秒數(shù)為
2*3600+5*60+7=7507秒。想想這個方法有哪些參數(shù),
返回值是什么類型。
8、寫一個方法交換整型列表中兩個指定下標(biāo)元素的值。
想想這個方法有哪些參數(shù),返回值是什么類型。
9、寫一個方法計算整型列表中所有能被3整除元素的個
數(shù)。想想這個方法有哪些參數(shù),返回值是什么類型。
10、寫一個方法將整型數(shù)字(int)轉(zhuǎn)換為格式化的字符串
(string),現(xiàn)要求如下:
a.可以指定轉(zhuǎn)換后[字符串的長度];
b.當(dāng)數(shù)字的長度不足指定的長度,讓這個字符串右對齊,
指定[左邊補(bǔ)的字符(char)];
例如,假設(shè)現(xiàn)在將指定的數(shù)字轉(zhuǎn)換為固定長度為8的字符
串,如果長度不足,左邊補(bǔ)'0',那么27這個數(shù)字就會轉(zhuǎn)換
為字符串"00000027"。
根據(jù)要求,想想這個方法有哪些參數(shù),返回值是什么類
型。
11.用方法實(shí)現(xiàn)找出一個int類型列表中最大值和最小值
12.判斷一個數(shù)是否是質(zhì)數(shù)(素數(shù))?該如何聲明方法?
13. 將指定的秒數(shù)轉(zhuǎn)變?yōu)閹仔r幾分幾秒。
14.使用Random類給一個數(shù)組的所有元素賦隨機(jī)初值(不
重復(fù))。
40/48
15.判斷一個整型數(shù)組是否是對稱的。所謂對稱就是第一
個元素等于最后一個元素,第二個元素等于倒數(shù)第二個元
素,依次類推,例如【7,3,1,3,7】就是對稱的。
16.打印一個元組的所有值。
17.查找一個元組中某個值是否存在,如果存在返回這個
值的索引,否則返回-1。
18.將一個列表反轉(zhuǎn)過來,比如【2,3,1,4,7】轉(zhuǎn)換為
【7,4,1,3,2】
19.求一個列表的最大值。
20.求一個列表的最小值。
21.寫一個方法,實(shí)現(xiàn)在列表中指定的的位置前插入一個
值。
22.寫一個方法,刪除列表中指定位置的元素。
23.猜數(shù)游戲
1.隨機(jī)出現(xiàn)一個數(shù)(范圍自定義) 作為答案
2.提示用戶輸入并根據(jù)答案和用戶輸入的大小關(guān)系輸出大
了? 小了?
3.5次機(jī)會
4.可以重復(fù)玩
5.根據(jù)猜對的次數(shù)進(jìn)行評價
6.無論對錯 請告知答案
8系統(tǒng)模塊
模塊的概念
模塊的引入
系統(tǒng)模塊os
操作模塊sys
數(shù)學(xué)模塊math
41/48
模塊的概念
模塊 是一個設(shè)計術(shù)語,是指對詞條中部分內(nèi)容進(jìn)行格式化
整理的模板。
例如歌手類詞條中的“音樂作品”模塊,電視劇類詞條的“分
集劇情”模塊。
在程序設(shè)計中,為完成某一功能所需的一段程序或子程序;
或指能由編譯程序、裝配程序等處理的獨(dú)立程序單位; 或指大型軟件系統(tǒng)的一部分。
模塊,又稱構(gòu)件,是能夠單獨(dú)命名并獨(dú)立地完成一定功能的
程序語句的集合(即程序代碼和數(shù)據(jù)結(jié)構(gòu)的集合體)。
它具有兩個基本的特征:外部特征和內(nèi)部特征。
外部特征是指模塊跟外部環(huán)境聯(lián)系的接口(即其他模塊或
程序調(diào)用該模塊的方式,包括有輸入輸出參數(shù)、引用的全
局變量)和模塊的功能;
內(nèi)部特征是指模塊的內(nèi)部環(huán)境具有的特點(diǎn)(即該模塊的局
部數(shù)據(jù)和程序代碼)。
Python 模塊(Module),是一個 Python 文件,以 .py 結(jié)
尾,包含了 Python 對象定義和Python語句。
模塊讓你能夠有邏輯地組織你的 Python 代碼段。
把相關(guān)的代碼分配到一個模塊里能讓你的代碼更好用,更
易懂。
模塊能定義函數(shù),類和變量,模塊里也能包含可執(zhí)行的代
碼。
模塊的引入
42/48
模塊的引入
import 語句
模塊定義好后,我們可以使用 import 語句來引入模塊
引入模塊的語法:
import Module[, module2[,... moduleN]
一次可以引入多個模塊,但是一般情況下 我們一次只引
入一個模塊.
當(dāng)解釋器遇到import語句,如果模塊在當(dāng)前的搜索路徑 就會被導(dǎo)入。
比如要引用模塊 math,就可以在文件最開始的地方用
import math 來引入。
在調(diào)用 math 模塊中的函數(shù)時,必須這樣引用:模塊
名.函數(shù)名一個模塊只會被導(dǎo)入一次,不管你執(zhí)行了多少次
import。這樣可以防止導(dǎo)入模塊被一遍又一遍地執(zhí)行。
有時候我們只需要用到模塊中的某個函數(shù),只需要引入
該函數(shù)即可,此時可以用下面方法實(shí)現(xiàn):
from 模塊名 import 函數(shù)名1,函數(shù)名2....
不僅可以引入函數(shù),還可以引入一些全局變量、類等
通過這種方式引入的時候,調(diào)用函數(shù)時只能給出函數(shù) 名,不能給出模塊名,但是當(dāng)兩個模塊中含有相同名稱函
數(shù)的時候,后面一次引入會覆蓋前一次引入。
也就是說假如模塊A中有函數(shù)function( ),在模塊B中
43/48
也有函數(shù)function( ),如果引入A中的function在先、B中
的function在后,那么當(dāng)調(diào)用function函數(shù)的時候,是去執(zhí)
行模塊B中的function函數(shù)。
如果想一次性引入math中所有的東西,還可以通過
from math import *來實(shí)現(xiàn)
系統(tǒng)模塊os
python編程時,經(jīng)常和文件、目錄打交道,這是就離不了
os模塊,os模塊包含普遍的操作系統(tǒng)功能,與具體的平臺無
關(guān).os 模塊提供了非常豐富的方法用來處理文件和目錄.
常用的如下:
os.path 獲取該模塊的路徑
os.name 獲取現(xiàn)在正在實(shí)用的平臺,Windows 返回 ‘nt';
Linux 返回’posix'
os.rename(originPath, targetPath) 重命名
os.remove(path) 刪除文件
os.mkdir(str) 創(chuàng)建文件夾
os.makedirs(path) 創(chuàng)建多個文件夾
os.getcwd() 獲得當(dāng)前路徑
os.chdir("../") 改變默認(rèn)目錄
os.listdir("./") 獲取目錄列表
os.rmdir(path) 刪除文件夾
獲取指定路徑下的文件
44/48
def f2(ph):
#獲取指定路徑下的文件夾和文件
file_list=os.listdir(ph)
#遍歷file_list集合
for f in file_list:
file=ph+os.sep+f
#如果是文件,直接打印文件名稱
if os.path.isfile(file):
print('這是一個文件:%s'%file)
#如果是文件夾
if os.path.isdir(file):
print('這是一個文件:%s'%file)
f2(file)
ph=input('請輸入路徑:')
f2(ph)
批量修改文件名
45/48
import os
import os.path
#得到完整路徑
path=input('請輸入完整的路徑:')
#獲取此路徑下的列表
all_file=os.listdir(path)
#改變當(dāng)前的工作路徑
#遍歷
for file in all_file:
#拼接路徑 將多個路徑組合后返回
old_path=os.path.join(path,file)
#判斷是否是文件
if os.path.isfile(old_path):
index=file.rfind('.')
#處理名字
new_name=file[0:index]+'-new'+file[index:]
else:
new_name=file+"-new"
new_path=os.path.join(path,new_name)
#重命名
os.rename(old_path,new_path)
獲得所有文件
46/48
#獲得文件夾里的所有內(nèi)容
#遞歸思路 在樹形結(jié)構(gòu)目錄里經(jīng)常使用
path=r"C:\Users\Administrator\Desktop"
def GetAllFile(path):
#不是目錄就跳出
if os.path.isdir(path):
pathList = os.listdir(path)
#是空目錄 也跳出來
if len(pathList) > 0:
for i in pathList:
tempPath = os.path.join(path, i)
print(tempPath)
#遞歸 調(diào)用自己
GetAllFile(tempPath)
GetAllFile(path)
操作模塊sys
sys模塊提供了一系列有關(guān)Python運(yùn)行環(huán)境的變量和函數(shù)
sys模塊常用的功能:
sys.argv 獲取當(dāng)前正在執(zhí)行的命令行參數(shù)的參數(shù)列表(list)
sys.platform 獲取當(dāng)前執(zhí)行環(huán)境的平臺,如win32表示是
Windows 32bit操作系統(tǒng),linux2表示是linusys.path 在
python啟動時,
sys.path根據(jù)內(nèi)建規(guī)則、PYTHONPATH變量進(jìn)行初始化。
sys.builtin_module_names 返回一個列表,包含內(nèi)建模塊
47/48
的名字
sys.exit(n) 調(diào)用sys.exit(n)可以中途退出程序,當(dāng)參數(shù)非
0時,會引發(fā)一個SystemExit異常,從而可以在主程序中 捕獲該異常。
數(shù)學(xué)模塊math
python中math模塊中提供的基本數(shù)學(xué)函數(shù)
sin(x):求x的正弦
cos(x):求x的余弦
asin(x):求x的反正弦
acos(x):求x的反余弦
tan(x):求x的正切
atan(x):求x的反正切
fmod(x,y):求x/y的余數(shù)
ceil(x):取不小于x的最小整數(shù)
floor(x):求不大于x的最大整數(shù)
fabs(x):求絕對值
pow(x,y):求x的y次冪
log10(x):求x的以10位底的對數(shù)
sqrt(x):求x的平方根
factorial(x) 求x的階乘
trunc(x) 求x的整數(shù)部分
總結(jié)
模塊的概念
模塊的引入
48/48
系統(tǒng)模塊os
操作模塊sys
數(shù)學(xué)模塊math
本章作業(yè)
必做:
1.當(dāng)前程序目錄下創(chuàng)建py文件夾,目錄里創(chuàng)建十個子文件
夾,并且命名為1-10
2.在子文件夾1-10里,偶數(shù)文件夾下創(chuàng)建新文件夾,命名
end
3.將子文件夾中2,4,8里的end重命名為end2,end4,
end8
4.刪除子文件2
5.打印py文件夾中所有文件夾名稱
6.刪除py及其所有子文件夾
7.浮點(diǎn)數(shù)20.73,向上取整,向下取整,正弦值
8.弧度π/4,π/2,對應(yīng)的度數(shù)