13-函數3
阿新 • • 發佈:2017-06-03
左面 cmd next 數據 sed __next__ calling cee inpu 目錄:匿名函數,內置函數,遞歸調用
匿名函數
lambda函數是一種快速定義單行的最小函數,可以用在任何需要函數的地方,執行完就會被回收
常規版本:
pow(2,3,5): 2表示底數,3表示指數,5表示取模,2^3 % 5 = 余數為3
divmod(9, 2): 9表示被除數,2表示除數,結果是元組形式的商合余數:(4,1)
max(1,2,10,100,98,20): 求最大值
min(1,2,10,100,98,20): 求最小值
sum(2,-5,9,12): 求和
2,工廠函數
int(),float(),str(),bool(),slice(),list(),tuple(),dict(),set(),frozenset()
int(‘5‘): 轉換為整數integer
float(2): 轉換為浮點數float
str(2.3): 轉換為字符串string
bool(0): 轉換為布爾值,結果是真還是假,0,‘‘,[],{},(),None均為False
slice(2,6,9):
list(1,2,3): 轉換為列表list
tuple([1,2,3]): 轉換為元組
dict(a=1,b=‘hello‘,c=[1,2,3]): 轉換為字典dict
set(): 轉換為集合
forzenset(): 創建不可修改的集合
3,類型類型轉換
ord(),chr(),bin(),hex(),oct(),complex()
print(ord(D)):將字母轉換為ASCII碼表上對應的數字
print(chr(9)):將數字轉換為ASCII碼表上對應的字母
print(hex(17)):轉換為十六進制
print(bin(5)):轉換為二進制
print(oct(2)):轉換為八進制
#復數,有實部和虛部(不常用)
res=complex(2+8j)
print(res.real)
print(res.imag)
4,序列操作
all(),any(),sorted(),reversed()
all([1,2,3]): 判斷是否為True,全部為真,才為真,有一個為假,則為假
any(0,1,None,3):判斷是否為真,只要有一個為真,就為真,如果全部為假,則為假
sorted([1,3,2]):從小到大排序
sorted([1,3,2].reverse=True):從大到小排序
reversed(1,3,2):從大到小排序
5,編譯執行函數
repr(),compile(),eval(),exec()
repr():返回對象me的字符串表示
print(type(repr(me)))
1,str
compile():解釋字符串表達式,參數也可以是compile()返回的code對象
print(compile(‘hello‘, ‘test.py‘))
<code object <module> at 0x0000000000A33540, file "test.py", line 1>
eval():
cmd = ‘print("你瞅啥")‘
eval(cmd) #可將字符串中的命令執行出來
運行結果:
你瞅啥
exec():
exec("print(‘hello‘)")
執行字符串或complie方法編譯過的字符串,沒有返回值
6,幫助函數
dir(),help(),id(),len(),challables()
v = []
print(dir(v)) # 查看v下面的屬性
print(help(v)) # 查看該對象的幫助文檔
print(id(v)) # 查看該對象的內存空間地址
print(len(v)) # 返回該對象的長度
print(challables(v)) # 判斷該對象是否可被調用,能被調用就是一個challables對象,比如函數和帶有__call__的實例
7,作用域查看
globals() #返回一個描述當前全局變量的字典
locals() #打印當前可用的局部變量的字典
vars() #當函數不接收參數時,其功能和locals函數一樣,返回當前作用域內的局部變量;
#當接收一個參數時,參數可以是模塊,類,類實例,或者定義了__dict__屬性的對象
8,叠代器函數
iter(),next(),enumerate(),range()
iter(o[, sentinel])
返回一個iterator對象。該函數對於第一個參數的解析依賴於第二個參數。如果沒有提供第二個參數,參數o必須是一個集合對象,支持遍歷功能(__iter__()方法)或支持序列功能(__getitem__()方法),參數為整數,從零開始。如果不支持這兩種功能,將處罰TypeError異常。如果提供了第二個參數,參數o必須是一個可調用對象。在這種情況下創建一個iterator對象,每次調用iterator的next()方法來無參數的調用o,如果返回值等於參數sentinel,觸發StopIteration異常,否則將返回該值。
next():返回一個可叠代數據結構中的下一項
enumerate(): 返回一個可以枚舉的對象,該對象的next()方法將返回一個元組
x = range(10)
enumerate([1,2,3]).__next__()
range():根據需要生成一個指定範圍的數字,可以提供你需要的控制來叠代指定的次數
9,其他
hash(),filter(),format(),input(),open(),print(),zip(),map(),__import__
hash():哈希值用於快遞比價字典的鍵。
1. 只要校驗的內容一致,那hash得到結果永遠一樣
2. 不可逆
3. 只要采用的哈希算法一樣,那無論被校驗的內容有多長,hash的到的結果長度都一樣
print(hash(‘sjfoiqwwrf‘))
print(hash(‘sjfoiqwwrf‘))
運行結果:
-6140230450656353267
-6140230450656353267
filter():過濾器
和map()類似,filter()也接收一個函數和一個序列。和map()不同的時,filter()把傳入的函數依次作用於每個元素,然後根據返回值是True還是False決定保留還是丟棄該元素
例如: l=[‘alex_sb‘, ‘wupeiqi_sb‘, ‘yuanhao_sb‘,‘egon‘] res=filter(lambda x:x.endswith(‘sb‘), l) print(res) print(list(res)) 運行結果: [‘alex_sb‘, ‘wupeiqi_sb‘, ‘yuanhao_sb‘] format():#格式化輸出字符串,format(value, format_spec)實質上是調用了value的__format__(format_spec)方法 ‘‘‘ "I am {0}, I like {1}!".format("wang", "moon") "I am {}, I like {}!".format("wang", "moon") "I am {name}, I like {msg}!".format(name = "wang", msg ="moon") ‘‘‘ input():#獲取用戶輸入內容 open():打開文件 print():輸出函數 zip():拉鏈函數 zip()是Python的一個內建函數,它接受一系列可叠代的對象作為參數,將對象中對應的元素按順序組合成一個tuple,每個tuple中包含的是原有序列中對應序號位置的元素,然後返回由這些tuples組成的list。若傳入參數的長度不等,則返回list的長度和參數中長度最短的對象相同。在所有參數長度相同的情況下,zip()與map()類似,沒有參數的情況下zip()返回一個空list
x = [1, 2, 3] y = [4, 5, 6] z = [7, 8, 9] xyz=zip(x,y,z) print(list(zip(*xyz))) 運行結果: [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
運行機制: 在運行zip(*xyz)之前,xyz的值是:[(1, 4, 7), (2, 5, 8), (3, 6, 9)] 那麽,zip(*xyz) 等價於 zip((1, 4, 7), (2, 5, 8), (3, 6, 9)) 所以,運行結果是:[(1, 2, 3), (4, 5, 6), (7, 8, 9)] map(function, iterable,...) map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,並把結果作為新的list返回,不會改變原數
例如: 為每個元素加一個‘sb‘字符串 l=[‘alex‘,‘wupeiqi‘,‘yuanhao‘] res=map(lambda x:x+‘_sb‘, l) print(res) print(list(res)) 運行結果: <map object at 0x0000000000830710> [‘alex_sb‘, ‘wupeiqi_sb‘, ‘yuanhao_sb‘] 獲取每個元素的平方 num=[2,4,6,8] res=map(lambda x:x**2, num) print(list(res)) 運行結果: [4, 16, 36, 64]
reduce(): reduce()函數接收的參數和 map()類似,一個函數 f,一個list,但行為和 map()不同,reduce()傳入的函數 f 必須接收兩個參數,reduce()對list的每個元素反復調用函數f,並返回最終結果值。 例如: l=[1,2,3,4,5] print(reduce(lambda x,y:x+y, l, [10])) #[10]是一個初始值,不指定則直接將第一次叠代出來的值作為初始值,指定後,則會將初始值與叠代出來的值做運算 運行結果: 25 它是這樣一個過程:每次叠代,將上一次的叠代結果(第一次時為init的元素,如沒有init則為seq的第一個元素)與下一個元素一同執行一個二元的func函數。在reduce函數中,init是可選的,如果使用,則作為第一次叠代的第一個元素使用。 10,面向對象使用的內置函數 super(),isinstance(),issubclass(),classmethod(),staticmethod(),proerty(),hasattr(),getattr(),setattr() super():調用父類的方法 isinstance():檢查對象是否是類的對象,返回True或False issubclass():檢查一個類是否是另一個類的子類。返回True或False classmethod():# 用來指定一個方法為類的方法,由類直接調用執行,只有一個cls參數,執行雷的方法時,自動將調用該方法的類賦值給cls.沒有此參數指定的類的方法為實例方法 staticmethod property delattr():# 刪除對象的屬性 hasattr hasattr(object,name) 判斷對象object是否包含名為name的特性(hasattr是通過調用getattr(object,name))是否拋出異常來實現的。 參數object:對象 參數name:特性名稱 >>> hasattr(list, ‘append‘) True >>> hasattr(list, ‘add‘) False getattr():獲取對象的屬性 setattr():與getattr()相對應 import time m=__import__(‘time‘) #以字符串的形式導入模塊 m.sleep(3000) 遞歸調用 在函數調用過程中,直接或間接調用了函數本身,就是函數的遞歸調用 1,必須有一個明確的結束條件 2,每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少 3,遞歸效率不高,遞歸層次過多會導致棧溢出[在計算機中,函數調用是通過stack棧這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以遞歸調用的次數過多,會導致棧溢出] 例如:
# 查看遞歸最大層數 import sys print(sys.getrecursionlimit()) #設置遞歸最大層數 print(sys.setrecursionlimit(10000))
典型示例:二分法 在一組數(可能會有成千上萬個)中,查找某個數是否存在
def fun(x,y): return x*y
lambda版本:
f=lambda x,y:x*y print(f(2,6))
示例:
salaries={‘egon‘:5000,‘alex‘:100000,‘wupeiqi‘:10000,‘yuanhao‘:2000} 要求:找出工資最高的人的名字
def func(k): return salaies[k] print(max(salaies, key=func)) 或 print(max(salaies, key=lambda k:salaries[k])) 要求按照工資大小進行排序: print(sorted(salaries, key=lambda x:salaries[x])) #默認從小到大 print(sorted(salaries, key=lambda x:salaries[x], reverse=True)) # 從大到小
內置函數: 1,數學運算 abs(),round(),pow(),divmod(),max(),min(),sum() abs(-1): 絕對值,結果是1 round(3.1415926, 4): 四舍五入,4為保留位數,結果是3.1416
例如: l=[‘alex_sb‘, ‘wupeiqi_sb‘, ‘yuanhao_sb‘,‘egon‘] res=filter(lambda x:x.endswith(‘sb‘), l) print(res) print(list(res)) 運行結果: [‘alex_sb‘, ‘wupeiqi_sb‘, ‘yuanhao_sb‘] format():#格式化輸出字符串,format(value, format_spec)實質上是調用了value的__format__(format_spec)方法 ‘‘‘ "I am {0}, I like {1}!".format("wang", "moon") "I am {}, I like {}!".format("wang", "moon") "I am {name}, I like {msg}!".format(name = "wang", msg ="moon") ‘‘‘ input():#獲取用戶輸入內容 open():打開文件 print():輸出函數 zip():拉鏈函數 zip()是Python的一個內建函數,它接受一系列可叠代的對象作為參數,將對象中對應的元素按順序組合成一個tuple,每個tuple中包含的是原有序列中對應序號位置的元素,然後返回由這些tuples組成的list。若傳入參數的長度不等,則返回list的長度和參數中長度最短的對象相同。在所有參數長度相同的情況下,zip()與map()類似,沒有參數的情況下zip()返回一個空list
x = [1, 2, 3] y = [4, 5, 6] z = [7, 8, 9] xyz=zip(x,y,z) print(list(zip(*xyz))) 運行結果: [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
運行機制: 在運行zip(*xyz)之前,xyz的值是:[(1, 4, 7), (2, 5, 8), (3, 6, 9)] 那麽,zip(*xyz) 等價於 zip((1, 4, 7), (2, 5, 8), (3, 6, 9)) 所以,運行結果是:[(1, 2, 3), (4, 5, 6), (7, 8, 9)] map(function, iterable,...) map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,並把結果作為新的list返回,不會改變原數
例如: 為每個元素加一個‘sb‘字符串 l=[‘alex‘,‘wupeiqi‘,‘yuanhao‘] res=map(lambda x:x+‘_sb‘, l) print(res) print(list(res)) 運行結果: <map object at 0x0000000000830710> [‘alex_sb‘, ‘wupeiqi_sb‘, ‘yuanhao_sb‘] 獲取每個元素的平方 num=[2,4,6,8] res=map(lambda x:x**2, num) print(list(res)) 運行結果: [4, 16, 36, 64]
reduce(): reduce()函數接收的參數和 map()類似,一個函數 f,一個list,但行為和 map()不同,reduce()傳入的函數 f 必須接收兩個參數,reduce()對list的每個元素反復調用函數f,並返回最終結果值。 例如: l=[1,2,3,4,5] print(reduce(lambda x,y:x+y, l, [10])) #[10]是一個初始值,不指定則直接將第一次叠代出來的值作為初始值,指定後,則會將初始值與叠代出來的值做運算 運行結果: 25 它是這樣一個過程:每次叠代,將上一次的叠代結果(第一次時為init的元素,如沒有init則為seq的第一個元素)與下一個元素一同執行一個二元的func函數。在reduce函數中,init是可選的,如果使用,則作為第一次叠代的第一個元素使用。 10,面向對象使用的內置函數 super(),isinstance(),issubclass(),classmethod(),staticmethod(),proerty(),hasattr(),getattr(),setattr() super():調用父類的方法 isinstance():檢查對象是否是類的對象,返回True或False issubclass():檢查一個類是否是另一個類的子類。返回True或False classmethod():# 用來指定一個方法為類的方法,由類直接調用執行,只有一個cls參數,執行雷的方法時,自動將調用該方法的類賦值給cls.沒有此參數指定的類的方法為實例方法 staticmethod property delattr():# 刪除對象的屬性 hasattr hasattr(object,name) 判斷對象object是否包含名為name的特性(hasattr是通過調用getattr(object,name))是否拋出異常來實現的。 參數object:對象 參數name:特性名稱 >>> hasattr(list, ‘append‘) True >>> hasattr(list, ‘add‘) False getattr():獲取對象的屬性 setattr():與getattr()相對應 import time m=__import__(‘time‘) #以字符串的形式導入模塊 m.sleep(3000) 遞歸調用 在函數調用過程中,直接或間接調用了函數本身,就是函數的遞歸調用 1,必須有一個明確的結束條件 2,每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少 3,遞歸效率不高,遞歸層次過多會導致棧溢出[在計算機中,函數調用是通過stack棧這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以遞歸調用的次數過多,會導致棧溢出] 例如:
def f1(): print(‘from f1‘) f1() f1()
python不會無限遞歸,當達到最大遞歸數時會提示錯誤並終端遞歸 RecursionError: maximum recursion depth exceeded while calling a Python object
# 查看遞歸最大層數 import sys print(sys.getrecursionlimit()) #設置遞歸最大層數 print(sys.setrecursionlimit(10000))
典型示例:二分法 在一組數(可能會有成千上萬個)中,查找某個數是否存在
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] def binary_search(dataset, find_num): print(dataset) if len(dataset) > 1: mid = int(len(dataset) // 2) if dataset[mid] == find_num: # find it print("找到數字", dataset[mid]) elif dataset[mid] > find_num: # 找的數在mid左面 print("\033[31;1m找的數在mid[%s]左面\033[0m" % dataset[mid]) return binary_search(dataset[0:mid], find_num) else: # 找的數在mid右面 print("\033[32;1m找的數在mid[%s]右面\033[0m" % dataset[mid]) return binary_search(dataset[mid + 1:], find_num) else: if dataset[0] == find_num: # find it print("找到數字啦", dataset[0]) else: print("沒的分了,要找的數字[%s]不在列表裏" % find_num) binary_search(data, 66) 運行結果: [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] 找的數在mid[18]右面 [20, 21, 22, 23, 30, 32, 33, 35] 找的數在mid[30]右面 [32, 33, 35] 找的數在mid[33]右面 [35] 沒的分了,要找的數字[66]不在列表裏
13-函數3