文章目錄
- 一、内置函數
-
- 1 作用域相關
- 2 其他
-
- Ⅰ 字元串類型代碼的執行:
- Ⅱ 輸入輸出相關:
- Ⅲ 資料類型相關:
- Ⅳ 記憶體相關:
- Ⅴ 檔案操作相關
- Ⅵ 子產品操作相關
- Ⅶ 幫助方法
- Ⅷ 調用相關
- Ⅸ 檢視參數所屬類型的所有内置方法
- 3 數字相關
- 4 資料結構相關
- 二、匿名函數
-
- 1 匿名函數格式的說明:
- 2 有名函數與匿名函數的對比:
- 3 lambda與内置函數結合使用
- 三、遞歸函數
-
- 1 遞歸調用的定義
- 2 遞歸調用的兩個階段:遞推,回溯
- 3 python中的遞歸
- 4 二分法
一、内置函數
截止到python版本3.6.2,現在python一共為我們提供了68個内置函數。它們就是python提供給你直接可以拿來使用的所有函數。

把這些函數分成了6大類:
1 作用域相關
基于字典的形式擷取局部變量和全局變量
globals()——擷取全局變量的字典
locals()——擷取執行本方法所在命名空間内的局部變量的字典
2 其他
Ⅰ 字元串類型代碼的執行:
eval() 将字元串類型的代碼執行并傳回結果
print(eval('1+2+3+4'))
# 10
**exec()**将自字元串類型的代碼執行
print(exec("1+2+3+4"))
exec("print('hello,world')")
# None
# hello,world
compile 将字元串類型的代碼編譯。代碼對象能夠通過exec語句來執行或者eval()進行求值。
參數說明:
- 參數source:字元串或者AST(Abstract Syntax Trees)對象。即需要動态執行的代碼段。
- 參數 filename:代碼檔案名稱,如果不是從檔案讀取代碼則傳遞一些可辨認的值。當傳入了source參數時,filename參數傳入空字元即可。
- 參數model:指定編譯代碼的種類,可以指定為 ‘exec’,’eval’,’single’。當source中包含流程語句時,model應指定為‘exec’;當source中隻包含一個簡單的求值表達式,model應指定為‘eval’;當source中包含了互動式指令語句,model應指定為’single’。
流程語句使用exec
code1 = 'for i in range(0,10): print (i)'
compile1 = compile(code1, '', 'exec')
exec(compile1)
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
簡單求值表達式用eval
code2 = '1 + 2 + 3 + 4'
compile2 = compile(code2, '', 'eval')
eval(compile2)
互動語句用single
code3 = 'name = input("please input your name:")'
compile3 = compile(code3,'','single')
name #執行前name變量不存在
#
Traceback (most recent call last):
File "D:\pystudy\fullstack\作業練習\腳本.py", line 3, in <module>
name #執行前name變量不存在
NameError: name 'name' is not defined
>>> exec(compile3) #執行時顯示互動指令,提示輸入
please input your name:'psych'
>>> name #執行後name變量有值
"'psych'"
Ⅱ 輸入輸出相關:
input() 輸入
s = input("請輸入内容 : ") #輸入的内容指派給s變量
print(s) #輸入什麼列印什麼。資料類型是str
print() 輸出
print源碼剖析
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
"""
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
file: 預設是輸出到螢幕,如果設定為檔案句柄,輸出到檔案
sep: 列印多個值之間的分隔符,預設為空格
end: 每一次列印的結尾,預設為換行符
flush: 立即把内容輸出到流檔案,不作緩存
"""
file關鍵字的說明
f = open('tmp_file','w')
print(123,456,sep=',',file = f,flush=True)
Ⅲ 資料類型相關:
type(o) 傳回變量o的資料類型
Ⅳ 記憶體相關:
id(o) o是參數,傳回一個變量的記憶體位址
hash(o) o是參數,傳回一個可hash變量的哈希值,不可hash的變量被hash之後會報錯。
t = (1,2,3)
l = [1,2,3]
print(hash(t)) #可hash
print(hash(l)) #會報錯
'''
結果:
TypeError: unhashable type: 'list'
'''
hash函數會根據一個内部的算法對目前可hash變量進行處理,傳回一個int數字。
注:每一次執行程式,内容相同的變量hash值在這一次執行過程中不會發生改變。
Ⅴ 檔案操作相關
open() 打開一個檔案,傳回一個檔案操作符(檔案句柄)
操作檔案的模式有r,w,a,r+,w+,a+ 共6種,每一種方式都可以用二進制的形式操作(rb,wb,ab,rb+,wb+,ab+)
可以用encoding指定編碼.
Ⅵ 子產品操作相關
__import__導入一個子產品
導入子產品:
import time
__import __:
os = __import__('os')
print(os.path.abspath('.'))
Ⅶ 幫助方法
在控制台執行help()進入幫助模式。可以随意輸入變量或者變量的類型。輸入q退出
或者直接執行help(o),o是參數,檢視和變量o有關的操作。。。
Ⅷ 調用相關
callable(o),o是參數,看這個變量是不是可調用。
如果o是一個函數名,就會傳回True
def func():pass
print(callable(func)) #參數是函數名,可調用,傳回True
print(callable(123)) #參數是數字,不可調用,傳回False
Ⅸ 檢視參數所屬類型的所有内置方法
dir() 預設檢視全局空間内的屬性,也接受一個參數,檢視這個參數内的方法或變量
print(dir(list)) #檢視清單的内置方法
print(dir(int)) #檢視整數的内置方法
3 數字相關
數字——資料類型相關:bool,int,float,complex
數字——進制轉換相關:bin,oct,hex
數字——數學運算:abs,divmod,min,max,sum,round,pow
4 資料結構相關
序列——清單和元組相關的:list和tuple
序列——字元串相關的:str,format,bytes,bytearry,memoryview,ord,chr,ascii,repr
bytearray:
ret = bytearray('psych',encoding='utf-8')
print(id(ret))
print(ret[0])
ret[0] = 65
print(ret)
print(id(ret))
# 2074162046256
# 97
# bytearray(b'Psych')
# 2074162046256
memoryview:
ret = memoryview(bytes('你好',encoding='utf-8'))
print(len(ret))
print(bytes(ret[:3]).decode('utf-8'))
print(bytes(ret[3:]).decode('utf-8'))
# 6
# 你
# 好
format:
- 函數功能将一個數值進行格式化顯示。
- 如果參數format_spec未提供,則和調用str(value)效果相同,轉換成字元串格式化。
>>> format(3.1415936)
'3.1415936'
>>> str(3.1415926)
'3.1415926'
- 對于不同的類型,參數format_spec可提供的值都不一樣
#字元串可以提供的參數,指定對齊方式,<是左對齊, >是右對齊,^是居中對齊
print(format('test', '<20'))
print(format('test', '>20'))
print(format('test', '^20'))
#整形數值可以提供的參數有 'b' 'c' 'd' 'o' 'x' 'X' 'n' None
>>> format(3,'b') #轉換成二進制
'11'
>>> format(97,'c') #轉換unicode成字元
'a'
>>> format(11,'d') #轉換成10進制
'11'
>>> format(11,'o') #轉換成8進制
'13'
>>> format(11,'x') #轉換成16進制 小寫字母表示
'b'
>>> format(11,'X') #轉換成16進制 大寫字母表示
'B'
>>> format(11,'n') #和d一樣
'11'
>>> format(11) #預設和d一樣
'11'
#浮點數可以提供的參數有 'e' 'E' 'f' 'F' 'g' 'G' 'n' '%' None
>>> format(314159267,'e') #科學計數法,預設保留6位小數
'3.141593e+08'
>>> format(314159267,'0.2e') #科學計數法,指定保留2位小數
'3.14e+08'
>>> format(314159267,'0.2E') #科學計數法,指定保留2位小數,采用大寫E表示
'3.14E+08'
>>> format(314159267,'f') #小數點計數法,預設保留6位小數
'314159267.000000'
>>> format(3.14159267000,'f') #小數點計數法,預設保留6位小數
'3.141593'
>>> format(3.14159267000,'0.8f') #小數點計數法,指定保留8位小數
'3.14159267'
>>> format(3.14159267000,'0.10f') #小數點計數法,指定保留10位小數
'3.1415926700'
>>> format(3.14e+1000000,'F') #小數點計數法,無窮大轉換成大小字母
'INF'
#g的格式化比較特殊,假設p為格式中指定的保留小數位數,先嘗試采用科學計數法格式化,得到幂指數exp,如果-4<=exp<p,則采用小數計數法,并保留p-1-exp位小數,否則按小數計數法計數,并按p-1保留小數位數
>>> format(0.00003141566,'.1g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科學計數法計數,保留0位小數點
'3e-05'
>>> format(0.00003141566,'.2g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科學計數法計數,保留1位小數點
'3.1e-05'
>>> format(0.00003141566,'.3g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科學計數法計數,保留2位小數點
'3.14e-05'
>>> format(0.00003141566,'.3G') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科學計數法計數,保留0位小數點,E使用大寫
'3.14E-05'
>>> format(3.1415926777,'.1g') #p=1,exp=0 ==》 -4<=exp<p成立,按小數計數法計數,保留0位小數點
'3'
>>> format(3.1415926777,'.2g') #p=1,exp=0 ==》 -4<=exp<p成立,按小數計數法計數,保留1位小數點
'3.1'
>>> format(3.1415926777,'.3g') #p=1,exp=0 ==》 -4<=exp<p成立,按小數計數法計數,保留2位小數點
'3.14'
>>> format(0.00003141566,'.1n') #和g相同
'3e-05'
>>> format(0.00003141566,'.3n') #和g相同
'3.14e-05'
>>> format(0.00003141566) #和g相同
'3.141566e-05'
序列:reversed,slice
reversed:
l = (1,2,23,213,5612,342,43)
print(l)
print(list(reversed(l)))
# (1, 2, 23, 213, 5612, 342, 43)
# [43, 342, 5612, 213, 23, 2, 1]
slice:
l = (1,2,23,213,5612,342,43)
sli = slice(1,5,2)
print(l[sli])
# (2, 213)
資料集合——字典和集合:dict,set,frozenset
資料集合:len,sorted,enumerate,all,any,zip,filter,map
filter:
filter()函數接收一個函數 f 和一個list,這個函數 f 的作用是對每個元素進行判斷,傳回 True或 False,filter()根據判斷結果自動過濾掉不符合條件的元素,傳回由符合條件元素組成的新list。
例如,要從一個list [1, 4, 6, 7, 9, 12, 17]中删除偶數,保留奇數,首先,要編寫一個判斷奇數的函數:
def is_odd(x):
return x % 2 == 1
然後,利用filter()過濾掉偶數:
list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17]))
# [1, 7, 9, 17]
利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字元串:
def is_not_empty(s):
return s and len(s.strip()) > 0
>>>list(filter(is_not_empty, ['test', None, '', 'str', ' ', 'END']))
結果:
注意: s.strip(rm) 删除 s 字元串中開頭、結尾處的 rm 序列的字元。
當rm為空時,預設删除空白符(包括’\n’, ‘\r’, ‘\t’, ’ '),如下:
>>> a = ' 123'
>>> a.strip()
'123'
>>> a = '\t\t123\r\n'
>>> a.strip()
'123'
map:
Python中的map函數應用于每一個可疊代的項,傳回的是一個結果list。如果有其他的可疊代參數傳進來,map函數則會把每一個參數都以相應的處理函數進行疊代處理。map()函數接收兩個參數,一個是函數,一個是序列,map将傳入的函數依次作用到序列的每個元素,并把結果作為新的list傳回。
有一個list, L = [1,2,3,4,5,6,7,8],我們要将f(x)=x^2作用于這個list上,那麼我們可以使用map函數處理。
>>> L = [1,2,3,4,]
>>> def pow2(x):
... return x*x
...
>>> list(map(pow2,L))
[1, 4, 9, 16]
sorted:
對List、Dict進行排序,Python提供了兩個方法
對給定的List L進行排序:
- 方法1.用List的成員函數sort進行排序,在本地進行排序,不傳回副本
- 方法2.用built-in函數sorted進行排序(從2.4開始),傳回副本,原始輸入不變
參數說明:
- iterable:是可疊代類型;
- key:傳入一個函數名,函數的參數是可疊代類型中的每一項,根據函數的傳回值大小排序;
- reverse:排序規則. reverse = True 降序 或者 reverse = False 升序,有預設值。
- 傳回值:有序清單
例:
清單按照其中每一個值的絕對值排序
l1 = [1,3,5,-2,-4,-6]
l2 = sorted(l1,key=abs)
print(l1)
print(l2)
# [1, 3, 5, -2, -4, -6]
# [1, -2, 3, -4, 5, -6]
二、匿名函數
為了解決那些功能很簡單的需求而設計的一句話函數
有名函數:
def calc(n):
return n**n
print(calc(10))
換成匿名函數:
calc = lambda n:n**n
print(calc(10))
1 匿名函數格式的說明:
函數名 = lambda 參數 :傳回值1.參數可以有多個,用逗号隔開
2.匿名函數不管邏輯多複雜,隻能寫一行,且邏輯執行結束後的内容就是傳回值
3.傳回值和正常的函數一樣可以是任意資料類型
2 有名函數與匿名函數的對比:
有名函數:循環使用,儲存了名字,通過名字就可以重複引用函數功能
匿名函數:一次性使用,随時随時定義
3 lambda與内置函數結合使用
字典的運算:最小值,最大值,排序
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
疊代字典,取得是key,因而比較的是key的最大和最小值
>>> max(salaries)
'yuanhao'
>>> min(salaries)
'alex'
可以取values,來比較
>>> max(salaries.values())
>>> min(salaries.values())
但通常我們都是想取出,工資最高的那個人名,即比較的是salaries的值,得到的是鍵
>>> max(salaries,key=lambda k:salary[k])
'alex'
>>> min(salaries,key=lambda k:salary[k])
'yuanhao'
也可以通過zip的方式實作
salaries_and_names=zip(salaries.values(),salaries.keys())
先比較值,值相同則比較鍵
>>> max(salaries_and_names)
(100000000, 'alex')
salaries_and_names是疊代器,因而隻能通路一次
>>> min(salaries_and_names)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence
sorted(iterable,key=None,reverse=False)
三、遞歸函數
1 遞歸調用的定義
遞歸調用是函數嵌套調用的一種特殊形式,函數在調用時,直接或間接調用了自身,就是遞歸調用
直接調用本身:
def f1():
print('from f1')
f1()
f1()
間接調用本身:
def f1():
print('from f1')
f2()
def f2():
print('from f2')
f1()
f1()
調用函數會産生局部的名稱空間,占用記憶體,因為上述這種調用會無需調用本身,python解釋器的記憶體管理機制為了防止其無限制占用記憶體,對函數的遞歸調用做了最大的層級限制
可以修改遞歸最大深度;
import sys
sys.getrecursionlimit()
sys.setrecursionlimit(2000)
def f1(n):
print('from f1',n)
f1(n+1)
f1(1)
雖然可以設定,但是因為不是尾遞歸,仍然要儲存棧,記憶體大小一定,不可能無限遞歸,而且無限制地遞歸調用本身是毫無意義的,遞歸應該分為兩個明确的階段,回溯與遞推
2 遞歸調用的兩個階段:遞推,回溯
回溯就是從外向裡一層一層遞歸調用下去,回溯階段必須要有一個明确地結束條件,每進入下一次遞歸時,問題的規模都應該有所減少(否則,單純地重複調用自身是毫無意義的)
遞推就是從裡向外一層一層結束遞歸
3 python中的遞歸
python中的遞歸效率低且沒有尾遞歸優化
python中的遞歸效率低,需要在進入下一次遞歸時保留目前的狀态,在其他語言中可以有解決方法:尾遞歸優化,即在函數的最後一步(而非最後一行)調用自己,尾遞歸優化:http://egon09.blog.51cto.com/9161406/1842475
但是python又沒有尾遞歸,且對遞歸層級做了限制
遞歸的使用:
- 必須有一個明确的結束條件
- 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
- 遞歸效率不高,遞歸層次過多會導緻棧溢出(在計算機中,函數調用是通過棧(stack)這種資料結構實作的,每當進入一個函數調用,棧就會加一層棧幀,每當函數傳回,棧就會減一層棧幀。由于棧的大小不是無限的,是以,遞歸調用的次數過多,會導緻棧溢出)
例:遞歸函數實作三級菜單
menu = {
'北京': {
'海澱': {
'五道口': {
'soho': {},
'網易': {},
'google': {}
},
'中關村': {
'愛奇藝': {},
'汽車之家': {},
'youku': {},
},
'上地': {
'百度': {},
},
},
'昌平': {
'沙河': {
'老男孩': {},
'北航': {},
},
'天通苑': {},
'回龍觀': {},
},
'朝陽': {},
'東城': {},
},
'上海': {
'闵行': {
"人民廣場": {
'炸雞店': {}
}
},
'閘北': {
'火車戰': {
'攜程': {}
}
},
'浦東': {},
},
'山東': {},
}
def threeLM(dic):
while True:
for k in dic:print(k)
key = input('input>>').strip()
if key == 'b' or key == 'q':return key
elif key in dic.keys() and dic[key]:
ret = threeLM(dic[key])
if ret == 'q': return 'q'
threeLM(menu)
4 二分法
想從一個按照從小到大排列的數字清單中找到指定的數字,周遊的效率太低,用二分法(算法的一種,算法是解決問題的方法)可以極大低縮小問題規模
例如:
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
觀察這個清單,這是不是一個從小到大排序的有序清單?
如果這樣,假如要找的數比清單中間的數還大,是不是直接在清單的後半邊找就行了?
這就是二分查找算法!
簡單版二分法:
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def func(l,aim):
mid = (len(l)-1)//2
if l:
if aim > l[mid]:
func(l[mid+1:],aim)
elif aim < l[mid]:
func(l[:mid],aim)
elif aim == l[mid]:
print("bingo",mid)
else:
print('找不到')
func(l,66)
func(l,6)
更新版二分法:
def search(num,l,start=None,end=None):
start = start if start else 0
end = end if end is not None else len(l) - 1
mid = (end - start)//2 + start
if start > end:
return None
elif l[mid] > num :
return search(num,l,start,mid-1)
elif l[mid] < num:
return search(num,l,mid+1,end)
elif l[mid] == num:
return mid