天天看點

内置函數和匿名函數

内置函數

接下來,我們就一起來看看python裡的内置函數。截止到python版本3.6.2,現在python一共為我們提供了68個内置函數。它們就是python提供給你直接可以拿來使用的所有函數。這些函數有些我們已經用過了,有些我們還沒用到過,還有一些是被封印了,必須等我們學了新知識才能解開封印的。那今天我們就一起來認識一下python的内置函數。這麼多函數,我們該從何學起呢?

Built-in Functions
abs() dict() help() min() setattr()
all() dir() hex() next() slice()
any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()
delattr() hash() memoryview() set()

上面就是内置函數的表,68個函數都在這兒了。這個表的順序是按照首字母的排列順序來的,你會發現都混亂的堆在一起。比如,oct和bin和hex都是做進制換算的,但是卻被寫在了三個地方。。。這樣非常不利于大家歸納和學習。那我把這些函數分成了6大類。你看下面這張圖,你猜咱們今天會學哪幾大類呀? 

我猜你們都猜對了。我們今天就要學習用粉紅色标注出來的這四大塊——56個方法。還有12個方法欠着怎麼辦呢?我們講完面向對象這剩下的12個會在兩周之内陸續還給你們的,我保證(認真臉)。那這樣,我們今天就主要關注我們要學習的這56個方法。

那要學的一共4塊,咱們從哪兒開始學起呢?

作用域相關

基于字典的形式擷取局部變量和全局變量

globals()——擷取全局變量的字典

locals()——擷取執行本方法所在命名空間内的局部變量的字典

其他

字元串類型代碼的執行

輸入輸出相關:

input() 輸入

s = input("請輸入内容 : ")  #輸入的内容指派給s變量
print(s)  #輸入什麼列印什麼。資料類型是str      
s = input("請輸入内容 : ")  #輸入的内容指派給s變量
print(s)  #輸入什麼列印什麼。資料類型是str      

print() 輸出

def print(self, *args, sep=' ', end='
', file=None): # known special case of print
    """
    print(value, ..., sep=' ', end='
', file=sys.stdout, flush=False)
    file:  預設是輸出到螢幕,如果設定為檔案句柄,輸出到檔案
    sep:   列印多個值之間的分隔符,預設為空格
    end:   每一次列印的結尾,預設為換行符
    flush: 立即把内容輸出到流檔案,不作緩存
    """      
def print(self, *args, sep=' ', end='
', file=None): # known special case of print
    """
    print(value, ..., sep=' ', end='
', file=sys.stdout, flush=False)
    file:  預設是輸出到螢幕,如果設定為檔案句柄,輸出到檔案
    sep:   列印多個值之間的分隔符,預設為空格
    end:   每一次列印的結尾,預設為換行符
    flush: 立即把内容輸出到流檔案,不作緩存
    """      
f = open('tmp_file','w')
print(123,456,sep=',',file = f,flush=True)      
f = open('tmp_file','w')
print(123,456,sep=',',file = f,flush=True)      
import time
for i in range(0,101,2):  
     time.sleep(0.1)
     char_num = i//2      #列印多少個'*'
     per_str = '
%s%% : %s
' % (i, '*' * char_num) if i == 100 else '
%s%% : %s'%(i,'*'*char_num)
     print(per_str,end='', flush=True)
#小越越  : 
 可以把光标移動到行首但不換行      
import time
for i in range(0,101,2):  
     time.sleep(0.1)
     char_num = i//2      #列印多少個'*'
     per_str = '
%s%% : %s
' % (i, '*' * char_num) if i == 100 else '
%s%% : %s'%(i,'*'*char_num)
     print(per_str,end='', 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'
'''      
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 time      
os = __import__('os')
print(os.path.abspath('.'))      
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      
def func():pass
print(callable(func))  #參數是函數名,可調用,傳回True
print(callable(123))   #參數是數字,不可調用,傳回False      

檢視參數所屬類型的所有内置方法

dir() 預設檢視全局空間内的屬性,也接受一個參數,檢視這個參數内的方法或變量

print(dir(list))  #檢視清單的内置方法
print(dir(int))  #檢視整數的内置方法      
print(dir(list))  #檢視清單的内置方法
print(dir(int))  #檢視整數的内置方法      

和數字相關

數字——資料類型相關:bool,int,float,complex

數字——進制轉換相關:bin,oct,hex

數字——數學運算:abs,divmod,min,max,sum,round,pow

和資料結構相關

序列——清單和元組相關的:list和tuple

序列——字元串相關的:str,format,bytes,bytearry,memoryview,ord,chr,ascii,repr

ret = bytearray('alex',encoding='utf-8')
print(id(ret))
print(ret[0])
ret[0] = 65
print(ret)
print(id(ret))      
ret = memoryview(bytes('你好',encoding='utf-8'))
print(len(ret))
print(bytes(ret[:3]).decode('utf-8'))
print(bytes(ret[3:]).decode('utf-8'))      

序列:reversed,slice

l = (1,2,23,213,5612,342,43)
print(l)
print(list(reversed(l)))      
l = (1,2,23,213,5612,342,43)
sli = slice(1,5,2)
print(l[sli])      

匿名函數

匿名函數:為了解決那些功能很簡單的需求而設計的一句話函數

#這段代碼
def calc(n):
    return n**n
print(calc(10))
 
#換成匿名函數
calc = lambda n:n**n
print(calc(10))      

上面是我們對calc這個匿名函數的分析,下面給出了一個關于匿名函數格式的說明

函數名 = lambda 參數 :傳回值

#參數可以有多個,用逗号隔開
#匿名函數不管邏輯多複雜,隻能寫一行,且邏輯執行結束後的内容就是傳回值
#傳回值和正常的函數一樣可以是任意資料類型      

我們可以看出,匿名函數并不是真的不能有名字。

匿名函數的調用和正常的調用也沒有什麼分别。 就是 函數名(參數) 就可以了~~~

練一練:

請把以下函數變成匿名函數
def add(x,y):
    return x+y      

上面是匿名函數的函數用法。除此之外,匿名函數也不是浪得虛名,它真的可以匿名。在和其他功能函數合作的時候

l=[3,2,100,999,213,1111,31121,333]
print(max(l))

dic={'k1':10,'k2':100,'k3':30}


print(max(dic))
print(dic[max(dic,key=lambda k:dic[k])])      
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)

輸出
1
25
49
16
64      
res = filter(lambda x:x>10,[5,8,11,9,15])
for i in res:
    print(i)

輸出
11
15      

面試題練一練

現有兩個元組(('a'),('b')),(('c'),('d')),請使用python中匿名函數生成清單[{'a':'c'},{'b':'d'}]

#答案一
test = lambda t1,t2 :[{i:j} for i,j in zip(t1,t2)]
print(test(t1,t2))
#答案二
print(list(map(lambda t:{t[0]:t[1]},zip(t1,t2))))
#還可以這樣寫
print([{i:j} for i,j in zip(t1,t2)])      
#答案一
test = lambda t1,t2 :[{i:j} for i,j in zip(t1,t2)]
print(test(t1,t2))
#答案二
print(list(map(lambda t:{t[0]:t[1]},zip(t1,t2))))
#還可以這樣寫
print([{i:j} for i,j in zip(t1,t2)])      
1.下面程式的輸出結果是:
d = lambda p:p*2
t = lambda p:p*3
x = 2
x = d(x)
x = t(x)
x = d(x)
print x

2.現有兩元組(('a'),('b')),(('c'),('d')),請使用python中匿名函數生成清單[{'a':'c'},{'b':'d'}]

3.以下代碼的輸出是什麼?請給出答案并解釋。
def multipliers():
    return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
請修改multipliers的定義來産生期望的結果。      
1.下面程式的輸出結果是:
d = lambda p:p*2
t = lambda p:p*3
x = 2
x = d(x)
x = t(x)
x = d(x)
print x

2.現有兩元組(('a'),('b')),(('c'),('d')),請使用python中匿名函數生成清單[{'a':'c'},{'b':'d'}]

3.以下代碼的輸出是什麼?請給出答案并解釋。
def multipliers():
    return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
請修改multipliers的定義來産生期望的結果。      

傳回頂部

本章小結

說學習内置函數,不如說整理自己的知識體系。其實整理這些内置函數的過程也是在整理自己的知識體系。

我們講課的時候會歸類:常用或者不常用,主要還是根據場景而言。

一個優秀的程式員就應該是在該用這個方法的時候信手拈來,把每一個内置的函數都用的恰到好處。

要想做到這一點,至少要先了解,才能在需要的時候想起,進而将它用在該用的地方。

但是在這裡,我還是以自己的一點經驗之談,把幾個平時工作中相對更常用的方法推薦一下,請務必重點掌握:

其他:input,print,type,hash,open,import,dir

str類型代碼執行:eval,exec

數字:bool,int,float,abs,divmod,min,max,sum,round,pow

序列——清單和元組相關的:list和tuple

序列——字元串相關的:str,bytes,repr

序列:reversed,slice

資料集合——字典和集合:dict,set,frozenset

資料集合:len,sorted,enumerate,zip,filter,map