函數是組織好的,可重複使用的,用來實現單一,或相關功能的代碼塊。python
函數分爲 Python 程序內置函數,用戶自定義的函數。將代碼定義爲函數,有以下好處:git
使用 def 關鍵字定義一個函數,後面緊跟函數名,小括號也必不可少,語法以下:算法
def func(): 函數體
函數在執行時,首先將函數體加載到解釋器中,可是不會運行,只有當調用函數後纔會執行,函數名+小括號便可調用函數:express
def func(): 函數體 func() # 調用函數
有時咱們須要函數返回一些數據來報告執行的結果,全部就須要有返回值,只須要在函數中添加 return 關鍵字,後面跟着返回值便可。編程
def func(): return 1
return 將返回值傳遞給函數自己,咱們只要調用函數,再將函數賦值給變量便可得到返回值:json
def func(): return 1 res = func() # 得到返回值,並賦值給變量 res print(res) 1
返回值能夠是 0 個,也能夠是 1 個 或多個:數組
def func(): # return # return 1 return 1, 2 res = func() print(res) None 1 (1, 2)
函數的參數能夠用函數實現個性化,大體分爲兩類:數據結構
形參只有在調用時才分配內存單元,調用結束,就釋放。僅在函數內部有效,不能在函數外部使用。閉包
實參能夠是常量、變量、表達式、函數,佔用內存空間。app
形參又分爲:默認參數、位置參數、關鍵字參數以及可變長參數,而默認參數即在函數定義時默認賦予某個形參一個值。若函數調用時,不傳入實參,函數使用默認值,不然使用實參。
def func(x=2): # x 默認爲 2 return x + 2 res = func() # 即便不傳入實參函數也能正常運行 print(res)
普通的參數即爲位置參數,在調用時實參必須與形參一一對應。而關鍵字參數,能夠不用考慮位置的關係,只須要名字相同便可。
def func(name, words): print(name: words) func('Hello', words='world') # 第一個爲位置參數,第二個爲關鍵字參數 func(words='World', name='Hello') # 不用考慮位置
Tips:位置參數必須在關鍵字參數後面
可變長參數是一種參數組,它能夠是多個參數,只須要在參數前加上星號(*)便可。它能夠增長函數可拓展性,當你不知道定義的函數須要定義幾個參數時,使用它很方便。
可變長參數分爲:*args 和 **kwargs兩類:
*args
*args 、**kwargs 是 Python 官方定義的參數名,也能夠是其餘名字,可是最好使用它,以便於辨認。
def func(*args): print(args) print('有 %d 個參數' % len(args)) print('第三個參數是:', args[2]) func('P', 'y', 't', 'h', 'o', 'n') func('Python', 123, '爬蟲')
('P', 'y', 't', 'h', 'o', 'n') 有 6 個參數 第三個參數是: t ('Python', 123, '爬蟲') 有 3 個參數 第三個參數是: 爬蟲
Tips:若是可變長參數後面還有參數,要將其定義爲關鍵字參數,不然會被收集成可變長參數裏面。建議在使用可變長參數時,可將其餘參數設置爲默認參數,或關鍵字參數,這樣不易混淆。
def func(*args, extra=16): # def func(*args, extra): print(args) print(extra) func(1,2,3) #func(5,6, extra=18) (1, 2, 3) 16 (5, 6) 18
星號()既可用來收集打包參數,也能夠用來「解包」參數。當傳入的參數時列表、元組、字典以及集合時,可變長參數將會將其整個打包成只有一個元組的參數,而在其前面添加一個星號( ),就能夠將裏面的元素一個個都解出來。
def func(*args): print(args) l = [1, 2, 3] t = (4, 5, 6) d = {'name':'rose', 'age': 18} func(l) func(*l) func(t) func(*t) func(d) func(*d)
([1, 2, 3],) (1, 2, 3) ((4, 5, 6),) (4, 5, 6) ({'name': 'rose', 'age': 18},) ('name', 'age')
**kwargs
另外一種可變長參數就是 **kwargs,它將傳入的實參打包成一個字典,一樣地也支持 「解包」。
def func(x, **kwargs): print(x) print(kwargs) print('總共有 %d 個參數' % len(kwargs)) print('這些參數分別爲:', kwargs) func(20, name='rose', age=18)
20 {'name': 'rose', 'age': 18} 總共有 2 個參數 這些參數分別爲: {'name': 'rose', 'age': 18}
解包,當傳入的參數是字典時:
def func(gender, **kwargs): print(gender) print(kwargs) print('總共有 %d 個參數' % len(kwargs)) print('這些參數分別爲:', kwargs) t = {'name': 'rose', 'age': 18} func('female', **t)
female {'name': 'rose', 'age': 18} 總共有 2 個參數 這些參數分別爲: {'name': 'rose', 'age': 18}
當既有 *args,又有 **kwargs,以及位置參數和位置參數時:
def func(gender, country='China', *args, **kwargs): print(gender, country) print(args) print(kwargs) func('male', 'America', 20, 30, name='rose', age=19)
male America (20, 30) {'name': 'rose', 'age': 19}
函數文檔即用來描述函數功能的文檔,可讓別人更好地理解你的函數,定義函數文檔是個好的習慣。
def func(x): """ 計算一個數加一 :param x: :return: """ x += 1 return x res = func()
在 Python 中函數和過程是分開的,函數(function)與過程(procedure)的區別:
嚴格來講 Python 沒有過程,只有函數,由於即便沒有返回值,也會默認返回一個 None。
def func(): print('Hi') res = func() print(res) Hi None
變量的做用域即變量可見性,也就是可用範圍,通常編程語言分爲:全局變量(global variable)和局部變量(local variable)。
當全局變量與局部變量同名是,在子程序中局部變量起做用,在外面全局變量起做用。
# 首先加載整個函數(不執行),調用函數執行函數內部,打印 tom,最後打印 rose name = 'rose' # 全局 def test(): name = 'tom' # 局部 print(name) test() print(name) tom rose
1. global 關鍵字
全局變量的做用域是整個程序,函數內部亦可訪問。可是不要在函數內部試圖修改全局變量,這是由於 Python 使用了屏蔽(shadowing)的方式去 保護全局變量。一旦在函數內部修改,則會在函數內部建立一個如出一轍的局部變量。
name = 'rose' def test(): name = 'tom' print(name) test() print(name) tom rose
從上面例子能夠看出,全局變量的值沒有改變。可是 Python 是支持在函數內部修改全局變量的,只須要在變量前面加上一個 global 關鍵字便可:
name = 'rose' def test(): global name name = 'tom' print(name) test() print(name) tom tom
總結:當全局與局部變量名字相同時,函數內部優先讀取局部變量。爲了更好地區分全局與局部變量,通常地全局變量名儘可能使用大小,局部變量名使用小寫。
2. 內嵌函數
函數支持嵌套,即一個函數中嵌套另一個函數,這種函數叫內嵌函數或內部函數。
name = 'rose' # (1) def fun1(): # (2) name = 'tom' # (5) def fun2(): # (6) name = 'lila' # (8) fun2() # (7) print(name) # (9) print(name) # (3) fun1() # (4) print(name) # (10) rose tom rose
Tips:內部函數只能在內部調用,外部調用會報 NameError
閉包(closure)是函數式編程中的一個重要數據結構,Python 中認爲若是在一個內部函數裏,對在外部做用域(但不是全局做用域)的變量進行引用,那麼這個內部函數就是閉包(closure)。
def fun1(x): def fun2(y): return x * y return fun2 a = fun1(6) # a 接收的是 fun2() 的內存地址 print(a) b = a(5) # a(5) 至關於調用 fun2() print(b) # 上述能夠簡寫 # res = fun1(6)(5) # print(res) <function fun1.<locals>.fun2 at 0x00000000026F48C8> 30
從上面的例子能夠看出,內部函數 fun2()對外部函數 fun1()的變量 x (不是全局變量)進行了引用,那麼 fun2()便是閉包。
nonlocal 關鍵字
但須要注意的是不能在外部函數外面調用內部函數,對外部函數的局部變量只能進行訪問,不能修改。
def fun1(): name = 'rose' def fun2(): name = 'tom' return name print(name) return fun2 fun1()() rose # 外部函數局部變量 name = ‘rose' 並無被修改
若是在內部函數中想修改外部函數的局部變量能夠用 nonlocal 關鍵字,可是須要注意的是它不能修改全局變量。
def fun1(): name = 'rose' def fun2(): nonlocal name # 添加 nonlocal 關鍵字 name = 'tom' return name print(name) return fun2 fun1()() tom # 外部函數局部變量 name = ‘rose' 已經被修改
Python 程序按程序執行,遇到函數,先加載到到內存,只有當調用函數時,纔會運行函數體。所以一個函數能夠做爲 變量在另外一個函數內部調用執行,前提是第一個函數須要先加載。
首先加載 f1()、f2(),再調用 f1(),執行 f1()裏的函數體,最後調用 f2(),執行 f2()裏的函數體:
def f1(): # (1) print('from f1') # (4) f2() # (5) def f2(): # (2) print('from f2') # (6) f1() # (3) from f1 from f2
另外一種狀況:
def f2(): print('from f2') def f1(): print('from f1') f2() f1() from f1 from f2
第三種狀況,調用 f2()時,由於 函數 f2()還未加載,致使出錯(NameError: name 'f2' is not defined
):
def f1(): print('from f1') f2() def f2(): print('from f2') f1()
在函數內部,能夠調用其餘函數,若是在調用過程當中直接或間接調用自身,那麼這個函數就是遞歸函數。
遞歸函數特徵:
函數調用是經過棧(stack)實現,每調用一次,棧就會增長一層棧幀,函數返回,則減小一層。因爲棧的大小有限,全部遞歸過多,就會致使棧溢出。
def func(n): print(n) if int(n/2) == 0: # 結束條件 return n res = func(int/2) # 調用自身 return res func(10) 10,5,2,1
遞歸問路
使用遞歸函數,實現一次遞歸問路操做。
import time person_list = ['rose', 'tom', 'lila', 'json', 'john'] def ask_way(person_list): """ 問路操做 :param person_list: 被問的人 :return: """ print('-'*60) if len(person_list) == 0: return '沒人知道' person = person_list.pop() if person == 'json': return '%s 我知道 xxx 怎麼走,它在 xxx' % person print('你好,%s,請問 xxx 在哪裏?' % person) print('%s 回答道:我也不知道,我幫你去問問 %s' % (person, person_list)) time.sleep(2) res = ask_way(person_list) return res res = ask_way(person_list) print(res)
------------------------------------------------------------ 你好,john,請問 xxx 在哪裏? john 回答道:我也不知道,我幫你去問問 ['rose', 'tom', 'lila', 'json'] ------------------------------------------------------------ json 我知道 xxx 怎麼走,它在 xxx
二分查找
data = [1,3,6,7,9,12,14,16,17,18,20,21,22,23,30,32,33,35] def find_num(data, num): """ 使用二分查找法,查找出一個數字的位置 """ print(data) if len(data) > 1: mid = int(len(data)/2) if data[mid] == num: print('找到數字', data[mid]) elif data[mid] > num: print('要找的數字在 %s 右邊' % data[mid]) return find_num(data[0:mid], num) else: print('要找的數字在 %s 左邊' % data[mid]) return find_num(data[mid+1:], num) else: if data[0] == num: print('找到數字', data[0]) else: print('要找的數字不在列表中') find_num(data, 66)
[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] 要找的數字在 18 左邊 [20, 21, 22, 23, 30, 32, 33, 35] 要找的數字在 30 左邊 [32, 33, 35] 要找的數字在 33 左邊 [35] 要找的數字不在列表中
尾調用又稱爲爲遞歸,指的是函數在最後一步調用另外一個函數的過程(最後一行不必定是最後一步)。
# bar 在 foo 內爲尾調用 def bar(n): return n def foo(m): return bar(m)
# bar 在 foo 內不是尾調用,最後一步爲 return y def bar(n): return n def foo(m): y = bar(m) return y
# bar一、bar2 在 foo 內都是尾調用 def bar1(n): return n def bar2(n): return n+1 def foo(x): if type(x) is str: return bar1(x) elif type(x) is int: return bar2(x)
尾調用優化
定義 a 函數,a 內調用 b,b 調用 c,在內存中造成一個調用記錄,又稱爲調用幀(call frame)。用於存儲調用位置和內部變量等信息,即(a——b——c),直至 c 返回結果給 b,c 的調用記錄消失。b 返回給 a,b 的調用記錄消失,a 返回結果,a 的調用記錄消失,全部記錄都是先進後出,造成一個調用棧(call stack)
匿名函數即不須要顯示地指定函數名的函數,Python 容許使用 lambda 關鍵字來建立一個匿名函數,匿名函數也被稱爲 lambda 表達式。
lambda x:x+2 lambda x,y,z:(x+1, y+1, z+1) # 多個參數
冒號左邊是原函數參數,能夠有多個參數,逗號分隔便可,冒號右邊爲返回值。對於有些結構比較簡單的函數,能夠直接定義爲匿名函數:
def func(x): return x+2 s = func(3) print(s)
上述函數可直接定義一個匿名函數:
f = lambda x:x+2 f(3) # 調用
匿名函數常與其餘函數搭配使用:
# 將 匿名函數當作參數傳入 calc 中 def calc(func, li): ret = [] for i in li: res = func(i) ret.append(res) return ret li = [2, 3, 4, 6, 8] calc(lambda x:x+1, li) [3, 4, 5, 7, 9]
lambda 表達式的做用:
當今編程的三種方法論:
函數式編程(函數+數學函數),更貼近數學,是一種抽象成都很高的編程範式,不容許函數有變量。但 Python 不是嚴格意義上的函數式編程,由於它容許有變量。
函數式編程特色:
函數即變量
def foo(n): print(n) def bar(name): print(name) foo(bar('rose')) rose None
上面例子中,bar('rose') 打印 rose,沒有返回值,所以 foo(bar('rose'))
至關於 foo(None)
。
返回值是函數
返回函數自己:
def handle(): print('from handle') return handle # 返回函數自己內存地址 h = handle() # 使用變量 h 接收 h() # 再調用函數自己 from handle from handle
返回別的函數:
def test(): print('from test') def test1(): print('from test1') return test # 返回 test 函數的內存地址 n = test1() # 接收 n() # 至關於調用 test()
函數式編程的兩個特徵:函數即變量,返回值是函數,只需知足其中一個條件,便可成爲高階函數。
def add(x, y, f): return f(x)+f(y) print(add(-5, 6, abs)) 11
上面例子中,內置函數 abs 做爲參數傳入函數 add。
map(function, sequence)
函數是高階函數的一種,它有兩個參數:第一個爲函數,另外一個接收一個序列。
其做用是將序列中每一個元素(for 循環),做爲函數參數傳入第一個參數中,直至序列中每一個元素都被循環,返回一個迭代器對象,用 list 可得到結果。
# 對列表 l 中每一個元素加 1 li = [2, 3, 4, 5, 6] def add_one(x): return x+1 res = map(add_one, li) print(res) print(list(res)) <map object at 0x0000000002C5C0B8> [3, 4, 5, 6, 7]
上面例子中 map 函數將列表 li 的每一箇中每一個元素取出,再傳入 add_one 中。
一樣地也可使用 lambda 表達式與 map 函數簡寫:
res = map(lambda x:x+1, li)
傳入兩個列表:
res = map(lambda x, y: x+y, [1, 3, 5], [2, 4, 6]) print(list(res))
filter(function or None, iterable)
函數有兩個參數:第一個能夠是函數也能夠是 None,第二個爲可迭代對象。
第一個參數爲函數:
# 過濾掉以 123 結尾的名字 names = ['rose_123', 'lila_123', 'john'] def filter_123(x): return not x.endswith('123') # 返回沒有以 123 結尾的名字 res = filter(filter_123, names) list(res) john
使用 lambda 表達式簡寫:
res = filter(lambda x: not x.endswith('123'), names) list(res)
第一個參數爲 None:
res = filter(None, [1, 2, 0, True, False]) list(res) [1, 2, True]
reduce(function, sequence[, initial])
函數三個參數:第一個爲函數,第二個爲序列,第三個可選爲初始值。
Python3 把 reduce 函數集成到 functools 模塊中,所以每次使用時,須要from functools import reduce
。它能夠把一個函數做用在一個序列上,這個函數必須接收兩個參數。首先將序列中的前兩個元素取出,傳入函數中,返回值再與序列中接下來的元素作累積計算,直至序列中的每一個元素都被循環。
求列表中全部元素的乘積:
常規:
nums = [1, 2, 3, 100] def reduce_test(func, array): res = array.pop(0) for i in array: res = func(res, i) return res s = reduce_test(lambda x,y: x*y, nums) print(s) 600
reduce:
from functools import reduce nums = [1, 2, 3, 100] res = reduce(lambda x,y : x*y, nums) print(res) 600
首先將 nums 前兩個元素,即 一、2 傳入lambda x,y: x*y
中,返回 x*y
。再將 3 傳入,最後將 100 傳入,至關於(((1*2)*3)*100)
。
指定初始值:
from functools import reduce nums = [1, 2, 3, 100] res = reduce(lambda x,y : x*y, nums, 6) # 至關於 (((6*1)*2)*3)*100 print(res) 3600
累加計算:
from functools import reduce reduce(lambda x,y: x+y, [1, 2, 3, 4, 5]) 15
排序算法在程序中是常常用到的算法,不管是冒泡仍是快排,其核心都是比較兩個元素的大小。
sorted(iterable, key, reverse)
函數也是一個高階函數,在列表內置方法中咱們就已經接觸到了,它能夠對一個列表進行排序,默認從小到大。
sorted([1, -3, 2]) [-3, 1, 2]
此外,它還接收一個 key 函數來自定義排序,key 函數做用在列表中的每一個元素上,再進行比較,如按絕對值排序:
sorted([1, -3, 2], key=abs) [1, 2, -3]
第三個參數 reverse,能夠反向排序:
sorted([1, -3, 2], key=abs, reverse=True) [-3, 2, 1]
上面都是針對數字的排序,直接比較其大小便可。可是對於字符串來講,通常地都是比較其首字母在 ASCII 中的大小:
sorted(['b', 'a', 'Z']) # 由於在 ASCII中 Z<a ['Z', 'a', 'b']
如今咱們不想按照 ASCII 來排序,而是按照字母表排序,那麼咱們能夠經過指定 key 函數,將全部字符串轉換爲大寫或小寫便可實現:
sorted(['b', 'a', 'Z'], key=str.upper) ['a', 'b', 'Z']
functools 模塊提供了不少功能,其中一個就是偏函數(partial )。
當函數的參數個數太多,須要簡化時,使用 functools.partial
建立一個偏函數,這個新的函數能夠固定住原函數的部分參數,從而調用更簡單。
語法結構:
from functools import partial func2 = partial(func, *args, **kwargs) # 第一個參數:要固定的函數,第二個:原函數的位置參數,第三個:關鍵字參數
第一個參數能夠是自定義的函數,也能夠是內置函數。
int() 函數能夠把字符串轉換爲整型,默認按照十進制轉換:
>>> int('123') 123
int() 函數還額外提供一個 base 參數,若是傳入 base,就能夠作 N 進制轉換:
>>> int('123', base=8) # 按照八進制轉換 83
內置函數
假如要轉換大量的二進制字符串,每次都要傳入 base,就會很繁瑣。咱們能夠利用偏函數(partial)將 base=2
固定住,定義一個新的函數,每次只須要傳入要轉換的字符串便可:
>>> from functools import partial >>> int2 = partial(int, base=2) # 將 base = 2 固定住 >>> int2('100') # 至關於 kw={'base': 2} int('100', **kw) 4
自定義函數
當咱們調用某個函數,已知某個參數的值時,能夠將其固定住(至關於設定默認值):
from functools import partial def add(x, y): return x % y add2 = partial(add, 5) # 自動將 5 做爲 *args 的一部分放在最左邊,也就是 5 % 100 print(add2(100)) # 101
將列表中年齡小於等於 18 歲的人過濾出來。
people = [ {'name': 'rose', 'age': 18}, {'name': 'lila', 'age': 30}, {'name': 'tom', 'age': 60} ] res = filter(lambda p: p.get('age') <= 18, people) print(list(res)) [{'name': 'rose', 'age': 18}]
函數分爲 Python 內置函數和自定義函數,內置函數有不少,可是真正能用到的也比較少。
# abs():求一個數字的絕對值 >>> abs(-5) 5 # all(iterable):判斷序列中全部元素是否爲 True,若是序列爲空,也返回 True,返回布爾值 >>> all([1, 2, 0]) False # any(iterable):序列中元素 bool(x),只要有一個爲 True,則返回 True,若是序列爲空,返回 False >>> any([]) False >>> any(['', 0, 1]) True # bin(number):十進制轉二進制 >>> bin(10) '0b1010' # hex(number):十進制轉十六進制 >>> hex(10) '0xa' # bool():轉換爲布爾類型 >>> bool(0) False >>> bool(None) False >>> bool('') False # bytes(obj,encoding=None):將對象編碼(二進制) # bytes(obj,encoding=None).decode(None):解碼,用什麼編碼就應用什麼解碼 >>> name = '你好' >>> bytes(name, encoding='utf-8') b'\xe4\xbd\xa0\xe5\xa5\xbd' >>> bytes(name, encoding='utf-8').decode('utf-8') '你好' # chr(i):返回一個數字在 ASCII 中對應的值 >>> chr(90) 'Z' # ord(obj):查詢一個字符咋 ASCII 中的對應的數字 >>> ord('Z') 90 # dict():建立一個字典 >>> d = dict() >>> type(d) <class 'dict'> # dir(obj):返回一個對象的全部方法名字 >>> dir(str) # help(obj):查看幫助文檔 >>> help(list.append) Help on method_descriptor: append(...) L.append(object) -> None -- append object to end # dirmod(x,y):返回一個元組,結果爲 x/有的商和餘數,通常用做網頁分頁 >>> divmod(10, 3) (3, 1) # id(obj):查看一個對象的內存地址 >>> id(10) 1750035808 # globals():查看全局變量 # locals():查看局部變量 # pow(x,y[,z]):冪運算,z 可選, pow(x,y,z)至關於 (x**y)%z >>> pow(10, 3) 1000 >>> pow(10, 3, 4) 0 # reversed(iterable):反轉一個序列 >>> list(reversed('abc')) ['c', 'b', 'a'] >>> list(reversed([1, 2, 3])) [3, 2, 1] # round(number,ndigits):四捨五入,保留幾位有效小數 >>> round(4.5) 4 >>> round(4.564, 2) 4.56 # set(iterable):轉換成集合、建立一個集合 >>> set('123') {'2', '3', '1'} >>> s = set() >>> type(s) <class 'set'> # slice(statr,stop[,step]):序列切片/分片 >>> l = 'hello' >>> s = slice(2, 3) >>> l[s] 'l' # str():轉換爲字符串 >>> str(123) '123' # sum(iterable, start=0):求序列中全部元素的和,還可指定 >>> l = [1, 2, 3, 4] >>> sum(l) 10 >>> sum(l, 1) 11 # tuple():轉換爲元組 >>> tuple(['a', 1]) ('a', 1) # vars(obj):返回對象的屬性和屬性值的字典對象。 >>> vars() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'name': '你好', 'd': "{'name:': ' rose'}", 's': slice(2, 3, None), 'p': {'name': 'rose', 'age': 18, 'gender': 'male'}, 't': <zip object at 0x0000000002D9FF08>, 'i': ('c', 3), 'age': {'rose': 18, 'tom': 19}, 'li': 'hello', 'l': [1, 2, 3, 4]} >>> vars(str) .... # __import__():當模塊名是字符串是,可使用。 >>> module_name = 'test' >>> __import__(module_name) <module 'test' from 'C:\\Users\\HJ\\Anaconda3\\lib\\test\\__init__.py'> >>> import module_name Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'module_name'
1. eval()
eval(expression,[globals[,locals])
,用於執行一個字符串表達式,並返回表達式值,能夠去掉字符串的引號。
>>> d = "{'name:': 'rose'}" >>> type(d) <class 'str'> >>> s = eval(d) >>> type(s) <class 'dict'>
字符串中表達式的值,也能夠計算:
>>> express = '1*2+3' >>> eval(express) 5
2. hash()
hash(obj)
作哈希運算,無論對象有多長,通過哈希運算後的值長度都相同,也不能根據 hash 值反推出原始對象。
可用於校對軟件/文件是否被別人篡改,還可用於判斷軟件或文件是否下載完整(檢驗官方給出的 hash 值與本身下載完畢 hash 的值是否相同)
>>> hash('abc') 5994226220732616244 >>> hash('123') -3466646395452377901
3. isinstance()、type()
兩個都是用於判斷數據類型,官方建議使用 isinstance。
>>> type(123) <class 'int'> nums = '123' if type(nums) is str: res = int(nums) + 1
isinstance(x,A_tuple)
有兩個參數:第一個是待肯定類型的數據,第二個是指定一個數據類型,判斷二者是否一致,返回一個布爾值。
>>> isinstance(123, int) True
4. zip()
zip(ite1[,iter2[...]])
函數接收兩個序列,要求它們元素數據相等,返回兩個序列元素一一對應的元組(返回的是 zip 對象的內存地址)。
>>> p = {'name': 'rose', 'age': 18, 'gender': 'male'} >>> t = zip(p.keys(), p.values()) >>> list(t) [('name', 'rose'), ('age', 18), ('gender', 'male')] >>> list(zip(['a', 'b', 'c'], [1, 2, 3])) [('a', 1), ('b', 2), ('c', 3)] >>> for i in zip(['a', 'b', 'c'], [1, 2, 3]): ... print(i) ... ('a', 1) ('b', 2) ('c', 3)
5. max()、min()
max(iterable, key, default)
、min()返回一個序列中的最大、小元素。
特性:
>>> max([1, 2, 3]) 3 >>> max(['a', 'b']) 'b' >>> max(['a12', 'a2']) # a 相同,2>1 'a2' # b>a >>> max(['a12', 'b10']) 'b10' >>> age = {'rose': 18, 'tom': 19} # 字典比較默認比較 key >>> max(age) 'tom' >>> max(zip(age.values(), age.keys())) # 既比較大小,又把名字也打印出來 (19, 'tom')
max()還能夠指定比較方法:
# 取出 age 比較 >>> people = [ {'name': 'rose', 'age': 18}, {'name': 'lila', 'age': 30}, {'name': 'tom', 'age': 60} ] >>> max(people, key=lambda dic:dic.get('age')) {'name': 'tom', 'age': 60}