冒泡排序算法的原理以下:(從後往前) 1.比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。 2.對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。 3.針對全部的元素重複以上的步驟,除了最後一個。 4.持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。
冒泡算法初級代碼以下:python
1 ##冒泡 2 a=[9,2,1,55,33] 3 4 for i in range(len(a)): 5 for j in range(len(a)-1): 6 if a[j] > a[j+1]: 7 middle = a[j] 8 a[j] = a[j+1] 9 a[j+1] = middle 10 else: 11 pass 12 13 print(a)
執行結果以下:web
[1, 2, 9, 33, 55]
代碼剖析:開始執行:初始列表a=[9,2,1,55,33],第一次外層循環i=0;第一次內層循環j=0;假如a[0]:9 > a[1]:2,交換位置,a[0]:2;a[1]:9,第二次內層循環j=1;假如a[1]:9 > a[2]:1,交換位置,第三次內層循環j=2;假如a[2]:9 > a[3]:55,不成立;pass,第四次內層循環j=3;假如a[3]:55 > a[4]:33,交換位置,內層循環結束,獲得結果a[4]==55,拿到第一大的值。第二次外層循環i=1;第一次內存循環j=0;假如a[0]:2 > a[1]:1,交換位置,第二次內層循環j=1;假如a[1]:2 > a[2]:9,不成立,pass,第三次內層循環j=2;假如a[2]:9> a[3]:33,不成立,pass,第四次內層循環j=3;假如a[3]:33 > a[4]:55,不成立,pass,拿到結果a[3] ==33,拿到第二大的值,以此類推。一個一個像冒泡同樣拿到最終的列表。正則表達式
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工做原理以下:
首先在未排序序列中找到最小元素,存放到排序序列的起始位置,而後,再從剩餘未排序元素中繼續尋找最小元素,而後放到排序序列末尾。以此類推,直到全部元素均排序完畢。
選擇排序初級代碼以下:算法
##選擇 b = [8,2,1,55,33] num = len(b)-1 for i in range(len(b)): index = 0 for j in range(num): if b[index] > b[j+1]: pass else: index = j+1 middle = b[num] b[num] = b[index] b[index] = middle num -= 1 print(b)
執行結果以下:shell
[1, 2, 8, 33, 55]
代碼剖析:開始執行:num==4;第一次外部循環i=0;index=0;第一次內部循環;j=0;假如b[0]:8 > b[1]:2;pass,第二次內部循環;j=1;假如b[0]:8 > b[2]:1;pass,第三次內部循環;j=2;假如b[0]:8 > b[3]:55;不成立,執行index = 3;第四次內部循環;j=3;假如b[3]:55 > b[4];pass;交換b[4] 和 b[3],通過第一次外部循環,拿到最大的值,放在最後,num=3;結束第一次外部循環。以此類推,獲得最終結果。選擇排序每次內部循環交換一次列表的值,比冒泡排序對列表的操做更少。編程
原理: 將n個元素的數列分爲已有序和無序兩個部分,如 插入排序過程示例 插入排序過程示例 下所示: {{a1},{a2,a3,a4,…,an}} {{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}} … {{a1(n-1),a2(n-1) ,…},{an(n-1)}} 每次處理就是將無序數列的第一個元素與有序數列的元素從後往前逐個進行比較,找出插入位置,將該元素插入到有序數列的合適位置中。 假設在一個無序的數組中,要將該數組中的數按插入排序的方法從小到大排序。假設啊a[]={3,5,2,1,4};插入排序的思想就是比大小,知足條件交換位置,一開始會像冒泡排序同樣,但會比冒泡多一步就是交換後(a[i]=a[i+1]後)原位置(a[i])會繼續和前面的數比較知足條件交換,直到a[i+1]前面的數組是有序的。好比在第二次比較後數組變成a[]={2,3,5,1,4};
插入排序初級代碼以下:數組
c=[6,4,3,22,12,8,9] for i in range(len(c)-1): flag = c[i+1] while i >= 0 and c[i] > flag: middle = c[i] c[i] = c[i+1] c[i+1] = middle i -= 1 print(c)
執行結果以下:安全
[3, 4, 6, 8, 9, 12, 22]
代碼剖析:執行開始:此時維護的有序列表爲[6],第一次外部循環;i=0;flag=c[1]=4;第一次內部循環;i=0 && c[0]:6 > 4,把c[1]放到c[0]後,結果如同交換c[0]和c[1],此時維護的有序列表爲[4,6],i=-1,退出內部循環。第二次外部循環;i=1;flag=c[2]=3;第一次內部循環;i=1 && c[1]:6 > 3,把c[2]放在c[1]前,如同交換,此時c[0]=4;c[1]=3;c[2]=6;而後進行i自減1;i=0;第二次內部循環;i=0 && c[0]:4 > 3,把c[1]放在c[0]前,如同交換,此時c[0]=3;c[1]=4;c[2]=6;退出內部循環。以此類推,拿到最終的列表。bash
liukai@bogon:~/PycharmProjects/s13/day6$ cat fanshe.py #!/usr/bin/env python3 # -*- coding=utf-8 -*- # Author : LiuKai def run(): inp = input("請輸入url: ") if inp.find("/") != -1: m,f = inp.split("/") obj = __import__(m) if hasattr(obj,f): func = getattr(obj,f) func() else: print("404") else: print("404") if __name__ == '__main__': run()liukai@bogon:~/PycharmProjects/s13/day6$ cat account.py #!/usr/bin/env python3 # -*- coding=utf-8 -*- # Author : LiuKai def login(): print("登錄頁面") def logout(): print("登出頁面") liukai@bogon:~/PycharmProjects/s13/day6$ cat order.py #!/usr/bin/env python3 # -*- coding=utf-8 -*- # Author : LiuKai def home(): print("主頁面")
執行fanshe.py結果以下:框架
請輸入url: account/login
登錄頁面
代碼需求分析:
1.實例分析:該代碼用反射來實現僞造web框架的路由系統
2.反射須要用到的方法:getattr、delattr、setattr、hasattr
3.導入模塊:import xxx、from xxx import ooo、__import__
代碼剖析:當輸入account/login時,m=account,f=login;__import__(m):__import__,能夠把字符串當作參數,導入這個模塊。正常import時,必須寫模塊名,不能以字符串的形式,這時候就須要__import__()了。這裏須要說一下,__import__()函數有個參數叫fromlist=True/False,當爲True時,能夠導入模塊的絕對路徑,例如:__import__(lib.m,fromlist=True),這能夠導入lib文件夾下的m模塊,假如不寫fromlist=True,只能導入lib模塊,就遺漏了m。回到剛纔,到入account模塊後,有個hasattr函數,這個函數的用途是,當模塊中有這個函數,返回True,不然返回False。接下來,getattr()函數,能夠從函數名字符串到函數引用的一個映射,getattr(obj,f)就至關於拿到了account模塊裏的login()函數,而後執行該函數。
官檔有更詳細的解釋,os就是提供對操做系統進行調用的接口
1 os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑 2 os.chdir("dirname") 改變當前腳本工做目錄;至關於shell下cd 3 os.curdir 返回當前目錄: ('.') 4 os.pardir 獲取當前目錄的父目錄字符串名:('..') 5 os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄 6 os.removedirs('dirname1') 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推 7 os.mkdir('dirname') 生成單級目錄;至關於shell中mkdir dirname 8 os.rmdir('dirname') 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname 9 os.listdir('dirname') 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印 10 os.remove() 刪除一個文件 11 os.rename("oldname","newname") 重命名文件/目錄 12 os.stat('path/filename') 獲取文件/目錄信息 13 os.sep 輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/" 14 os.linesep 輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" 15 os.pathsep 輸出用於分割文件路徑的字符串 16 os.name 輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix' 17 os.system("bash command") 運行shell命令,直接顯示 18 os.environ 獲取系統環境變量 19 os.path.abspath(path) 返回path規範化的絕對路徑 ###經常使用 20 os.path.split(path) 將path分割成目錄和文件名二元組返回 21 os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 ##經常使用 22 os.path.basename(path) 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素 23 os.path.exists(path) 若是path存在,返回True;若是path不存在,返回False 24 os.path.isabs(path) 若是path是絕對路徑,返回True 25 os.path.isfile(path) 若是path是一個存在的文件,返回True。不然返回False 26 os.path.isdir(path) 若是path是一個存在的目錄,則返回True。不然返回False 27 os.path.join(path1[, path2[, ...]]) 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 ##經常使用 28 os.path.getatime(path) 返回path所指向的文件或者目錄的最後存取時間 29 os.path.getmtime(path) 返回path所指向的文件或者目錄的最後修改時間
hashlib模塊主要用於加密相關的操做。
import hashlib obj = hashlib.md5(bytes("lk",encoding='utf8')) obj.update(bytes("123",encoding="UTF-8")) result = obj.hexdigest() print(result)
執行結果以下:
a0a58adb9fd5bb904f771e6e7d619ffb
代碼剖析:上面代碼中要給字符串'123'進行加密,bytes("lk",encoding="uft8")的意思是在123的基礎上再次按照字符串"lk"加密。這樣作會更加安全。hexdigest()函數輸出加密後的值。
1 sys.argv 命令行參數List,第一個元素是程序自己路徑 2 sys.exit(n) 退出程序,正常退出時exit(0) 3 sys.version 獲取Python解釋程序的版本信息 4 sys.maxint 最大的Int值 5 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 6 sys.platform 返回操做系統平臺名稱
利用sys模塊模擬進度條:
import sys import time def view_bar(num, total): rate = float(num) / float(total) rate_num = int(rate * 100) # r = '\r%s%d%%' % ("=" * num,rate_num, ) r = '\r[{:100s}]{:d}%'.format("+" * num,rate_num) sys.stdout.write(r) sys.stdout.flush() if __name__ == '__main__': for i in range(0, 101): time.sleep(0.05) view_bar(i, 100)
執行結果以下:
[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]100%
代碼剖析:\r表明return,光標回到當前行首,能實現進度條的效果。sys.stdout.write()屏幕輸出,sys.stdout.flush()方法的功能是:強制把緩衝器的內容刷到終端。
正則表達式並非Python的一部分。正則表達式是用於處理字符串的強大工具,擁有本身獨特的語法以及一個獨立的處理引擎,效率上可能不如str自帶的方法,但功能十分強大。得益於這一點,在提供了正則表達式的語言裏,正則表達式的語法都是同樣的,區別只在於不一樣的編程語言實現支持的語法數量不一樣;但不用擔憂,不被支持的語法一般是不經常使用的部分。若是已經在其餘語言裏使用過正則表達式,只須要簡單看一看就能夠上手了。
下圖展現了使用正則表達式進行匹配的流程:
正則表達式的大體匹配過程是:依次拿出表達式和文本中的字符比較,若是每個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。若是表達式中有量詞或邊界,這個過程會稍微有一些不一樣,但也是很好理解的,看下圖中的示例以及本身多使用幾回就能明白。
下圖列出了Python支持的正則表達式元字符和語法:
簡單正則舉例:
import re str1 = "lk lk666 *_lk lk /lklk01" result1 = re.findall(r".",str1) print("result1:",result1) result2 = re.findall(r".*",str1) print("result2:",result2) result3 = re.findall(r".+",str1) print("result3:",result3) result4 = re.findall(r".?",str1) print("result4:",result4) result5 = re.findall(r"\d",str1) print("result5:",result5) result6 = re.findall(r"\w",str1) print("result6:",result6) result7 = re.findall(r"\s",str1) print("result7:",result7) result8 = re.findall(r"\D",str1) print("result8:",result8) result9 = re.findall(r"\W",str1) print("result9:",result9) result10 = re.findall(r"\S",str1) print("result10:",result10) result11 = re.findall(r"^lk",str1) print("result11:",result11) result12 = re.findall(r"01$",str1) print("result12:",result12) result13 = re.findall(r"\d{2}",str1) print("result13:",result13) result14 = re.findall(r"\blk\b",str1) print("result14:",result14) result15 = re.findall(r"[lL]k",str1) print("result15:",result15) result16 = re.findall(r"\b[^\d]k\b",str1) print("result16:",result16)
執行結構以下:
result1: ['l', 'k', ' ', 'l', 'k', '6', '6', '6', ' ', '*', '_', 'l', 'k', ' ', 'l', 'k', ' ', '/', 'l', 'k', 'l', 'k', '0', '1'] result2: ['lk lk666 *_lk lk /lklk01', ''] result3: ['lk lk666 *_lk lk /lklk01'] result4: ['l', 'k', ' ', 'l', 'k', '6', '6', '6', ' ', '*', '_', 'l', 'k', ' ', 'l', 'k', ' ', '/', 'l', 'k', 'l', 'k', '0', '1', ''] result5: ['6', '6', '6', '0', '1'] result6: ['l', 'k', 'l', 'k', '6', '6', '6', '_', 'l', 'k', 'l', 'k', 'l', 'k', 'l', 'k', '0', '1'] result7: [' ', ' ', ' ', ' '] result8: ['l', 'k', ' ', 'l', 'k', ' ', '*', '_', 'l', 'k', ' ', 'l', 'k', ' ', '/', 'l', 'k', 'l', 'k'] result9: [' ', ' ', '*', ' ', ' ', '/'] result10: ['l', 'k', 'l', 'k', '6', '6', '6', '*', '_', 'l', 'k', 'l', 'k', '/', 'l', 'k', 'l', 'k', '0', '1'] result11: ['lk'] result12: ['01'] result13: ['66', '01'] result14: ['lk', 'lk'] result15: ['lk', 'lk', 'lk', 'lk', 'lk', 'lk'] result16: ['lk', 'lk']
代碼剖析:就不解釋了,直接看上圖吧。。。
正則表達式一般用於在文本中查找匹配的字符串。Python裏數量詞默認是貪婪的(在少數語言裏也多是默認非貪婪),老是嘗試匹配儘量多的字符;非貪婪的則相反,老是嘗試匹配儘量少的字符。例如:正則表達式"ab*"若是用於查找"abbbc",將找到"abbb"。而若是使用非貪婪的數量詞"ab*?",將找到"a"。
與大多數編程語言相同,正則表達式裏使用"\"做爲轉義字符,這就可能形成反斜槓困擾。假如你須要匹配文本中的字符"\",那麼使用編程語言表示的正則表達式裏將須要4個反斜槓"\\\\":前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可使用r"\\"表示。一樣,匹配一個數字的"\\d"能夠寫成r"\d"。有了原生字符串,你不再用擔憂是否是漏寫了反斜槓,寫出來的表達式也更直觀。
re.compile(strPattern[, flag]):
compile()方法是Pattern類的工廠方法,用於將字符串形式的正則表達式編譯爲Pattern對象,
第二個參數flag是匹配模式,取值可使用按位或運算符'|'表示同時生效,好比re.I | re.M。另外,你也能夠在regex字符串中指定模式,好比re.compile('pattern', re.I | re.M)與re.compile('(?im)pattern')是等價的。
可選值有:
import re str2 = "lk1kaks618fuck" c = re.compile("[a-z]{1,4}") result = re.match(c,str2) print(result.group())
執行結果以下:
lk
代碼剖析:c爲定義了一個Pattern對象,就是那個正則規則。好處是能夠供屢次使用,相似變量的功效。
match(string[, pos[, endpos]]) | re.match(pattern, string[, flags]):
這個方法將從string的pos下標處起嘗試匹配pattern;若是pattern結束時仍可匹配,則返回一個Match對象;若是匹配過程當中pattern沒法匹配,或者匹配未結束就已到達endpos,則返回None。
pos和endpos的默認值分別爲0和len(string);re.match()沒法指定這兩個參數,參數flags用於編譯pattern時指定匹配模式。
注意:這個方法並非徹底匹配。當pattern結束時若string還有剩餘字符,仍然視爲成功。想要徹底匹配,能夠在表達式末尾加上邊界匹配符'$'。
import re
str2 = "lk1kaks618fuck"
c = re.compile("[a-z]{1,2}")
result = re.match(c,str2)
print(result.group())
print(result.groups())
print(result.string)
print(result.re)
print(result.pos)
print(result.endpos)
print(result.lastindex)
print(result.start())
print(result.group())
print(result.groupdict())
print(result.end())
print(result.span()[1])
執行結果以下:
lk
()
lk1kaks618fuck
re.compile('[a-z]{1,2}')
0
14
None
0
lk
{}
2
2
代碼剖析:
Match對象是一次匹配的結果,包含了不少關於這次匹配的信息,可使用Match提供的可讀屬性或方法來獲取這些信息。
屬性:
方法:
注:match()方法只是匹配字符串開頭,假如正則規則匹配的在中間,則沒法匹配,須要下面的search()方法。
search(string[, pos[, endpos]]) | re.search(pattern, string[, flags]):
這個方法用於查找字符串中能夠匹配成功的子串。從string的pos下標處起嘗試匹配pattern,若是pattern結束時仍可匹配,則返回一個Match對象;若沒法匹配,則將pos加1後從新嘗試匹配;直到pos=endpos時仍沒法匹配則返回None。
pos和endpos的默認值分別爲0和len(string));re.search()沒法指定這兩個參數,參數flags用於編譯pattern時指定匹配模式。
import re str2 = "lk1kaksklk618fuck" c = re.compile("[a-z]{1,2}") result = re.search(c,str2) print(result.group())
執行結果以下:
lk
代碼剖析:search()從開頭匹配假如匹配不到也能夠繼續向後匹配,這是和match()的不一樣之處。
split(string[, maxsplit]) | re.split(pattern, string[, maxsplit]):
按照可以匹配的子串將string分割後返回列表。maxsplit用於指定最大分割次數,不指定將所有分割。
import re str2 = "lk1kaks618fuck55" c = re.compile(r"[a-z]{1,2}") result = re.split(c,str2) print(result)
執行結果以下:
['', '1', '', '618', '', '55']
代碼剖析:這個相似於字符串的split()方法,不過比那個更增強大,能夠根據正則規則分隔,split的maxsplit參數能夠指定分隔多少次。
findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags]):
搜索string,以列表形式返回所有能匹配的子串。
import re str2 = "lk1kaks618fuck55" c = re.compile(r"[a-z]{1,2}") result = re.findall(c,str2) print(result)
執行結果以下:
['lk', 'ka', 'ks', 'fu', 'ck']
代碼剖析:這個findall()方法很經常使用,匹配的結果以列表的形式表示,很方便處理。
sub(repl, string[, count]) | re.sub(pattern, repl, string[, count]):
使用repl替換string中每個匹配的子串後返回替換後的字符串。
當repl是一個字符串時,可使用\id或\g<id>、\g<name>引用分組,但不能使用編號0。
當repl是一個方法時,這個方法應當只接受一個參數(Match對象),並返回一個字符串用於替換(返回的字符串中不能再引用分組)。
count用於指定最多替換次數,不指定時所有替換。
import re
str2 = "lk1kaks618fuck55"
c = re.compile(r"[a-z]{1,2}")
result = re.sub(c,"xx",str2,count=2)
print(result)
執行結果以下:
xx1xxks618fuck55
代碼剖析:count能夠指定替換的次數,默認是所有。還有個subn()函數,用法同樣,不過能夠返回一個元組,第一個元素爲替換後的字符串,第二個元素是替換的次數。
import re str3 = "aaa bbb ccc aaa ccc ddd" r = re.split("ccc", str3, 1) print(r) #====================== str4 = "aaa ddd acc ddd acc ddd aaa" r1 = re.split("(acc)", str4) print(r1) r2 = re.split("(a(cc))", str4) print(r2)
執行結果以下:
['aaa bbb ', ' aaa ccc ddd'] ['aaa ddd ', 'acc', ' ddd ', 'acc', ' ddd aaa'] ['aaa ddd ', 'acc', 'cc', ' ddd ', 'acc', 'cc', ' ddd aaa']
代碼剖析:split()的無分組狀況就是正常分隔,當有分組時,也會打印相應分組的字符串,當有兩個以上括號時,都會打印出來。
findall()、match()、search()的分組方法如例子:
import re str3 = "aaa bbb ccc aaa ccc ddd" r = re.findall("\w{3} c", str3) print(r) # 有分組 str4 = "aaa ddd acc ddd acc ddd aaa" r1 = re.findall("(\w{3}) a", str4) print(r1) r2 = re.match("(^aaa) d",str4) r3 = re.search("(\w{2})\w",str4) print(r2.groups()[0]) print(r3.groups()[0])
執行結果以下:
['bbb c', 'aaa c'] ['ddd', 'ddd', 'ddd'] aaa aa