python之內建函式(二)與匿名函式、遞迴函式初識
一、內建函式(二)
1、和資料結構相關(24)
列表和元祖(2)
list:將一個可迭代物件轉化成列表(如果是字典,預設將key作為列表的元素)。
tuple:將一個可迭代物件轉化成元組(如果是字典,預設將key作為元組的元素)
2、相關內建函式(2)
reversed:將一個序列翻轉,並返回此翻轉序列的迭代器。 *****
slice:構造一個切片模板,用於列表的切片。***
2-1、reversed()與列表的reverse()區分:
列表的reverse()只能列表使用:列表.reverse(),對原列表進行翻轉,結果返回的還是列表。
內建函式reversed(),將一個序列翻轉,結果是返回一個迭代器。
列表的reverse()
l1 = [1,3,4,2,6] l1.reverse() #將列表進行翻轉 print(l1) #返回修改後的列表[6, 2, 4, 3, 1]
內建函式reversed()
reversed(l1) #生成一個迭代器 print(reversed(l1)) #一個地址 for i in reversed(l1): print(i) # 結果: # 用for迴圈輸出迭代器的值 # 6 2 4 3 1 # 字串使用reversed() s1 = 'abcdefg' for i in reversed(s1): print(i) 結果: g f e d c b a # 字典使用reversed() 報錯 dic = {'name':'xiaoming','age':1000,'hobby':'oldwomen'} # 不行
2-2、slice:構造一個切片模板,用於列表的切片。 ***
l3 = [1,2,3,4,5,6,7,8,9,10]
sli_obj = slice(0,5,2) #製作切片模板,索引從0到4,間隔取值
print(l3[sli_obj]) # [1 3 5]
l4 = ['a', 'b', 'c', 'd', 'e']
print(l4[sli_obj]) # ['a', 'c', 'e']
3、字串相關(9)
3-1、str:將資料轉化成字串。
3-2、format:與具體資料相關,用於計算各種小數,精算等。 **
平常使用format情況較少,下面這種形式已經是最多的了,剩下的科學運算,需要用到的可自行研究。
字串可以提供的引數,指定對齊方式,<是左對齊, >是右對齊,^是居中對齊
print(format('test', '<20')) # 左對齊 (20是長度)
print(format('test', '>20')) # 右對齊
print(format('test', '^20')) # 居中對齊
3-3、bytes:unicode ---> bytes型別(單向的編碼) ****
# 編碼encode(): s1 = '小明' b1 = s1.encode('utf-8') print(b1) # b'\xe5\xb0\x8f\xe6\x98\x8e' # 解碼decode(): s2 = b1.decode('utf-8') print(s2) # 小明 # 用bytes()方法編碼(單向) a1 = '小白' b1 = bytes(a1,encoding='utf-8') print(b1) # b'\xe5\xb0\x8f\xe7\x99\xbd' # 不能用bytes()方法解碼 a2 = bytes(b1,encoding='utf-8') print(a2) # 報錯 # 只能用decode()解碼 a2 = b1.decode('utf-8') print(a2) #小白
3-4、bytearry:返回一個位元組陣列。這個數組裡的元素是可變的,並且每個元素的值範圍: 0 <= x < 256。
(bytearray其實也是一種編碼的方法,不過bytearray可對編碼後的位元組進行修改,即對原資料進行修改)
例如:字串 小明
b1 = bytearray('小明',encoding='utf-8') #對小明進行編碼,生成一串位元組碼(utf-8一箇中文代表三個位元組)
print(b1) # bytearray(b'\xe5\xb0\x8f\xe6\x98\x8e')
print(b1[0]) # 229
b1[0] = 65 #對前三個位元組進行修改(即修改中文'小')
b1[1] = 97
b1[2] = 104
print(b1) # bytearray(b'Aah\xe6\x98\x8e')
print(b1.decode('utf-8')) # 解碼出來:Aah明
例如:字串 hot
ret = bytearray('hot',encoding='utf-8')
print(id(ret)) # 2997820203056
print(ret) # bytearray(b'hot')
print(ret[0]) # h的ASCII:104
ret[0] = 65 # 把索引0的ASCII值改為65(A)
print(ret) # bytearray(b'Aot') hot索引0就改成了A
print(id(ret)) # 2997820203056 記憶體地址不變
3-5、memoryview
ret = memoryview(bytes('你好',encoding='utf-8'))
print(len(ret)) # 6
print(ret) # <memory at 0x000001D3D6FCD048> # [\xe4,\xbd,\xa0,\xe5,\xa5,\xbd]
print(bytes(ret[:3]).decode('utf-8')) # 你
print(bytes(ret[3:]).decode('utf-8')) # 好
3-6、ord:輸入字元找該字元unicode編碼的位置 **
print(ord('a')) # 97
print(ord('中')) # 20013
3-7、chr:輸入位置數字找出其對應的unicode編碼的字元 **
print(chr(97)) # a
print(chr(20013)) # 中
3-8、ascii:在ascii碼中的就返回該值,不是則返回它在unicode的位置(16進位制。) **
print(ascii('a')) # 'a'
print(ascii('中')) # '\u4e2d'
3-9、repr:返回一個物件的string形式(原形畢露) *****
print(repr('{"name":"xiaoming"}')) #'{"name":"xiaoming"}' print('{"name":"xiaoming"}') # {"name":"xiaoming"} 格式化輸出%r--->原封不動的寫出來(基礎資料型別都可接收) 字串單雙引號都預設是單引號 msg = 'xiaoming是%r的人' % ('德高望重') print(msg) # xiaoming是'德高望重'的人 msg = 'xiaoming是%r的人' % ("德高望重") print(msg) # xiaoming是'德高望重'的人 msg = 'xiaoming是%r的人' %(18) print(msg) # xiaoming是18的人 msg = 'xiaoming是%r的人' %(True) print(msg) # xiaoming是True的人 msg = 'xiaoming是%r的人' %({'name':'xiaming','age':18}) print(msg) # xiaoming是{'name': 'xiaming', 'age': 18}的人 repr():可用於判斷json pickle序列化模組 特殊字串,python字串的區別
4、資料集合(3)
4-1、dict:建立一個字典。
4-2、set:建立一個集合。
4-3、frozenset:返回一個凍結的集合,凍結後集合不能再新增或刪除任何元素。
5、相關內建函式(8)
5-1、len:返回一個物件中元素的個數。
5-2、sorted:對所有可迭代的物件進行排序操作。 *****
與列表的sort區分:
列表的sort方法是對原列表進行排序修改,並沒有生成新的列表
內建函式sorted方法會形成一個新列表
l1 = [2,3,5,3,1,9,8,6] l1.sort() print(l1) print(sorted(l1)) # 形成了一個新列表 print(l1) # 原列表不變 內建函式sorted還可以與函式結合使用 l2 = [(1,1000),(2,18),(4,250),(3,500)] def func1(x): return x[1] print(sorted(l2,key=func1)) #按第二個元素升序排序 [(2, 18), (4, 250), (3, 500), (1, 1000)] print(sorted(l2,key=func1,reverse=True)) #按第二個元素降序排序 [(1, 1000), (3, 500), (4, 250), (2, 18)]
5-3、enumerate:列舉,返回一個列舉物件。****
一個值接收列舉物件,返回的每個元素是元組,元組第一個元素是索引(預設從0開始)
第二個元素是可迭代物件的每個元素。
for i in enumerate([1,2,3]):
print(i)
結果:
(0, 1)
(1, 2)
(2, 3)
for i in enumerate([1,2,3],100):
print(i)
結果:
(100, 1)
(101, 2)
(102, 3)
for i,j in enumerate([1,2,3],100):
print(i,j)
結果:
100 1
101 2
102 3
5-4、all:可迭代物件中,全都是True才是True *** 多做條件判斷
l1 = [1,'',[1,3],(2,4)]
print(all(l1)) #False 有一個元素是空
5-5、any:可迭代物件中,有一個True就是True *** 多做條件判斷
l2 = [1,0,'',()]
print(any(l2)) #True
5-6、拉鍊方法:zip() 將多個iter縱向組成元素為元組的迭代器,以長度最小的iterable為標準長度 *****
l1 = [1,2,3,4] tu1 = ('a','b','c') dic = {'name':'xiaoming','age':18,'hobby':'girl','hometown':'guangzhou'} zip(l1,tu1,dic) #迭代器(生成器物件) print(zip(l1,tu1,dic)) #迭代器地址:<zip object at 0x000002C878E6A6C8> for i in zip(l1,tu1,dic): print(i) #迴圈輸出迭代器的內容: (1, 'a', 'name') (2, 'b', 'age') (3, 'c', 'hobby')
5-7、filter:過濾,通過你的函式,過濾一個可迭代物件(類似於生成器表示式的篩選模式) 生成一個迭代器。 *****
l1 = [1,2,3,4,5,6] def fun(x): return x % 2 == 0 #篩選出偶數 g = filter(fun,l1) # filter(fun,l1)生成的是一個迭代器 print(g) for i in g: print(i) 結果: 2 4 6 l2 = [(2,1),(3,4),(4,5)] def fun2(x): return x[1] % 2 == 1 #篩選出第二個元素為奇數的元組 g = filter(fun2,l2) for i in g: print(i) 結果: (2, 1) (4, 5)
5-8、map:會根據提供的函式對指定序列做對映。(迴圈修改並返回) 生成一個迭代器*****
l1 = [1,2,3,4,5,6] def fun(x): return x**2 #返回每個元素的平方 g = map(fun,l1) for i in g: print(i) 結果:1 4 9 16 25 36
(min max filter返回的都是遍歷的引數,map返回的是return的值)
二、匿名函式:有且只有返回值的函式才可以用匿名函式進行簡化,一行函式,多與內建函式結合使用。
1、匿名函式表示式:
函式名 = lambda 引數 :返回值
引數可以有多個,用逗號隔開
匿名函式不管邏輯多複雜,只能寫一行,且邏輯執行結束後的內容就是返回值
返回值和正常的函式一樣可以是任意資料型別
2、
def func2(x):
return x**2
上面函式就有且只有返回值,所以可以寫成匿名函式:
func2 = lambda x: x*2 #func2是函式名,func2(引數)才是呼叫
print(func2(6)) #呼叫並列印結果
3、匿名函式 不單獨使用,多與內建函式結合。
l2 = [(1,1000),(2,18),(4,250),(3,500)]
print(sorted(l2,key=lambda x:x[1]))
4、例子
1,利用內建函式匿名函式將dic按照值進行排序。 dic={'k1':10,'k2':100,'k3':30} print(sorted(dic.items(),key=lambda x:x[1])) 2,利用內建函式匿名函式 計算列表的每個數的2倍。 l1 = [1,5,7,4,8] print(list(map(lambda x:x*2,l1))) 3,利用內建函式匿名函式,將值大於10的留下來 l2 = [5,8,11,9,15] print(list(filter(lambda x:x > 10,l2))) 4,匿名函式可與三元運算結合 func = lambda x:x if x > 2 else x * 2
三、遞迴函式(自己呼叫自己)
1、人理解函式,神理解遞迴。
def func():
print(666)
func()
func()
結果:輸出一段時間後會報錯,因為
預設遞迴深度為998次,(官方給出的預設深度是1000,但實際上只有998次左右)
超過了就會報錯
2、引用模組修改遞迴次數
import sys
sys.setrecursionlimit(100000)
n = 1
def func(x):
print(x)
x += 1
func(x)
func(n)
結果:3222
雖然設定了100000次,但是電腦跑不起呀,
一般電腦就跑3222次左右,這個會根據電腦效能而定。
3、
小明比小白大兩歲 n = 4
小白比小狗大兩歲 n= 3
小狗比小紅大兩歲 n = 2
小紅24歲 n = 1
小明多少歲?
def age(n):
if n == 1:
return 24
else:
return age(n-1) + 2
age(4) # 30
詳解:
age(4)傳進引數n=4:
def age(4):
if n == 1:
return 24
else:
return age(4-1) + 2
結果:age(3)+2
def age(3):
if n == 1:
return 24
else:
return age(3-1) + 2
結果:age(2)+2+2
def age(2):
if n == 1:
return 24
else:
return age(2-1) + 2
結果:age(1)+2+2+2
def age(1):
if n == 1:
return 24
else:
return age(n-1) + 2
結果:age(1)+2+2+2 ---> 24+2+2+2--->30
一、內建函式(二)
1、和資料結構相關(24)
列表和元祖(2)
list:將一個可迭代物件轉化成列表(如果是字典,預設將key作為列表的元素)。
tuple:將一個可迭代物件轉化成元組(如果是字典,預設將key作為元組的元素)
2、相關內建函式(2)
reversed:將一個序列翻轉,並返回此翻轉序列的迭代器。 *****
slice:構造一個切片模板,用於列表的切片。***
2-1、reversed()與列表的reverse()區分:
列表的reverse()只能列表使用:列表.reverse(),對原列表進行翻轉,結果返回的還是列表。
內建函式reversed(),將一個序列翻轉,結果是返回一個迭代器。
列表的reverse()
l1 = [1,3,4,2,6] l1.reverse() #將列表進行翻轉 print(l1) #返回修改後的列表[6, 2, 4, 3, 1]
內建函式reversed()
reversed(l1) #生成一個迭代器 print(reversed(l1)) #一個地址 for i in reversed(l1): print(i) # 結果: # 用for迴圈輸出迭代器的值 # 6 2 4 3 1 # 字串使用reversed() s1 = 'abcdefg' for i in reversed(s1): print(i) 結果: g f e d c b a # 字典使用reversed() 報錯 dic = {'name':'xiaoming','age':1000,'hobby':'oldwomen'} # 不行
2-2、slice:構造一個切片模板,用於列表的切片。 ***
l3 = [1,2,3,4,5,6,7,8,9,10]
sli_obj = slice(0,5,2) #製作切片模板,索引從0到4,間隔取值
print(l3[sli_obj]) # [1 3 5]
l4 = ['a', 'b', 'c', 'd', 'e']
print(l4[sli_obj]) # ['a', 'c', 'e']
3、字串相關(9)
3-1、str:將資料轉化成字串。
3-2、format:與具體資料相關,用於計算各種小數,精算等。 **
平常使用format情況較少,下面這種形式已經是最多的了,剩下的科學運算,需要用到的可自行研究。
字串可以提供的引數,指定對齊方式,<是左對齊, >是右對齊,^是居中對齊
print(format('test', '<20')) # 左對齊 (20是長度)
print(format('test', '>20')) # 右對齊
print(format('test', '^20')) # 居中對齊
3-3、bytes:unicode ---> bytes型別(單向的編碼) ****
# 編碼encode(): s1 = '小明' b1 = s1.encode('utf-8') print(b1) # b'\xe5\xb0\x8f\xe6\x98\x8e' # 解碼decode(): s2 = b1.decode('utf-8') print(s2) # 小明 # 用bytes()方法編碼(單向) a1 = '小白' b1 = bytes(a1,encoding='utf-8') print(b1) # b'\xe5\xb0\x8f\xe7\x99\xbd' # 不能用bytes()方法解碼 a2 = bytes(b1,encoding='utf-8') print(a2) # 報錯 # 只能用decode()解碼 a2 = b1.decode('utf-8') print(a2) #小白
3-4、bytearry:返回一個位元組陣列。這個數組裡的元素是可變的,並且每個元素的值範圍: 0 <= x < 256。
(bytearray其實也是一種編碼的方法,不過bytearray可對編碼後的位元組進行修改,即對原資料進行修改)
例如:字串 小明
b1 = bytearray('小明',encoding='utf-8') #對小明進行編碼,生成一串位元組碼(utf-8一箇中文代表三個位元組)
print(b1) # bytearray(b'\xe5\xb0\x8f\xe6\x98\x8e')
print(b1[0]) # 229
b1[0] = 65 #對前三個位元組進行修改(即修改中文'小')
b1[1] = 97
b1[2] = 104
print(b1) # bytearray(b'Aah\xe6\x98\x8e')
print(b1.decode('utf-8')) # 解碼出來:Aah明
例如:字串 hot
ret = bytearray('hot',encoding='utf-8')
print(id(ret)) # 2997820203056
print(ret) # bytearray(b'hot')
print(ret[0]) # h的ASCII:104
ret[0] = 65 # 把索引0的ASCII值改為65(A)
print(ret) # bytearray(b'Aot') hot索引0就改成了A
print(id(ret)) # 2997820203056 記憶體地址不變
3-5、memoryview
ret = memoryview(bytes('你好',encoding='utf-8'))
print(len(ret)) # 6
print(ret) # <memory at 0x000001D3D6FCD048> # [\xe4,\xbd,\xa0,\xe5,\xa5,\xbd]
print(bytes(ret[:3]).decode('utf-8')) # 你
print(bytes(ret[3:]).decode('utf-8')) # 好
3-6、ord:輸入字元找該字元unicode編碼的位置 **
print(ord('a')) # 97
print(ord('中')) # 20013
3-7、chr:輸入位置數字找出其對應的unicode編碼的字元 **
print(chr(97)) # a
print(chr(20013)) # 中
3-8、ascii:在ascii碼中的就返回該值,不是則返回它在unicode的位置(16進位制。) **
print(ascii('a')) # 'a'
print(ascii('中')) # '\u4e2d'
3-9、repr:返回一個物件的string形式(原形畢露) *****
print(repr('{"name":"xiaoming"}')) #'{"name":"xiaoming"}' print('{"name":"xiaoming"}') # {"name":"xiaoming"} 格式化輸出%r--->原封不動的寫出來(基礎資料型別都可接收) 字串單雙引號都預設是單引號 msg = 'xiaoming是%r的人' % ('德高望重') print(msg) # xiaoming是'德高望重'的人 msg = 'xiaoming是%r的人' % ("德高望重") print(msg) # xiaoming是'德高望重'的人 msg = 'xiaoming是%r的人' %(18) print(msg) # xiaoming是18的人 msg = 'xiaoming是%r的人' %(True) print(msg) # xiaoming是True的人 msg = 'xiaoming是%r的人' %({'name':'xiaming','age':18}) print(msg) # xiaoming是{'name': 'xiaming', 'age': 18}的人 repr():可用於判斷json pickle序列化模組 特殊字串,python字串的區別
4、資料集合(3)
4-1、dict:建立一個字典。
4-2、set:建立一個集合。
4-3、frozenset:返回一個凍結的集合,凍結後集合不能再新增或刪除任何元素。
5、相關內建函式(8)
5-1、len:返回一個物件中元素的個數。
5-2、sorted:對所有可迭代的物件進行排序操作。 *****
與列表的sort區分:
列表的sort方法是對原列表進行排序修改,並沒有生成新的列表
內建函式sorted方法會形成一個新列表
l1 = [2,3,5,3,1,9,8,6] l1.sort() print(l1) print(sorted(l1)) # 形成了一個新列表 print(l1) # 原列表不變 內建函式sorted還可以與函式結合使用 l2 = [(1,1000),(2,18),(4,250),(3,500)] def func1(x): return x[1] print(sorted(l2,key=func1)) #按第二個元素升序排序 [(2, 18), (4, 250), (3, 500), (1, 1000)] print(sorted(l2,key=func1,reverse=True)) #按第二個元素降序排序 [(1, 1000), (3, 500), (4, 250), (2, 18)]
5-3、enumerate:列舉,返回一個列舉物件。****
一個值接收列舉物件,返回的每個元素是元組,元組第一個元素是索引(預設從0開始)
第二個元素是可迭代物件的每個元素。
for i in enumerate([1,2,3]):
print(i)
結果:
(0, 1)
(1, 2)
(2, 3)
for i in enumerate([1,2,3],100):
print(i)
結果:
(100, 1)
(101, 2)
(102, 3)
for i,j in enumerate([1,2,3],100):
print(i,j)
結果:
100 1
101 2
102 3
5-4、all:可迭代物件中,全都是True才是True *** 多做條件判斷
l1 = [1,'',[1,3],(2,4)]
print(all(l1)) #False 有一個元素是空
5-5、any:可迭代物件中,有一個True就是True *** 多做條件判斷
l2 = [1,0,'',()]
print(any(l2)) #True
5-6、拉鍊方法:zip() 將多個iter縱向組成元素為元組的迭代器,以長度最小的iterable為標準長度 *****
l1 = [1,2,3,4] tu1 = ('a','b','c') dic = {'name':'xiaoming','age':18,'hobby':'girl','hometown':'guangzhou'} zip(l1,tu1,dic) #迭代器(生成器物件) print(zip(l1,tu1,dic)) #迭代器地址:<zip object at 0x000002C878E6A6C8> for i in zip(l1,tu1,dic): print(i) #迴圈輸出迭代器的內容: (1, 'a', 'name') (2, 'b', 'age') (3, 'c', 'hobby')
5-7、filter:過濾,通過你的函式,過濾一個可迭代物件(類似於生成器表示式的篩選模式) 生成一個迭代器。 *****
l1 = [1,2,3,4,5,6] def fun(x): return x % 2 == 0 #篩選出偶數 g = filter(fun,l1) # filter(fun,l1)生成的是一個迭代器 print(g) for i in g: print(i) 結果: 2 4 6 l2 = [(2,1),(3,4),(4,5)] def fun2(x): return x[1] % 2 == 1 #篩選出第二個元素為奇數的元組 g = filter(fun2,l2) for i in g: print(i) 結果: (2, 1) (4, 5)
5-8、map:會根據提供的函式對指定序列做對映。(迴圈修改並返回) 生成一個迭代器*****
l1 = [1,2,3,4,5,6] def fun(x): return x**2 #返回每個元素的平方 g = map(fun,l1) for i in g: print(i) 結果:1 4 9 16 25 36
(min max filter返回的都是遍歷的引數,map返回的是return的值)
二、匿名函式:有且只有返回值的函式才可以用匿名函式進行簡化,一行函式,多與內建函式結合使用。
1、匿名函式表示式:
函式名 = lambda 引數 :返回值
引數可以有多個,用逗號隔開
匿名函式不管邏輯多複雜,只能寫一行,且邏輯執行結束後的內容就是返回值
返回值和正常的函式一樣可以是任意資料型別
2、
def func2(x):
return x**2
上面函式就有且只有返回值,所以可以寫成匿名函式:
func2 = lambda x: x*2 #func2是函式名,func2(引數)才是呼叫
print(func2(6)) #呼叫並列印結果
3、匿名函式 不單獨使用,多與內建函式結合。
l2 = [(1,1000),(2,18),(4,250),(3,500)]
print(sorted(l2,key=lambda x:x[1]))
4、例子
1,利用內建函式匿名函式將dic按照值進行排序。 dic={'k1':10,'k2':100,'k3':30} print(sorted(dic.items(),key=lambda x:x[1])) 2,利用內建函式匿名函式 計算列表的每個數的2倍。 l1 = [1,5,7,4,8] print(list(map(lambda x:x*2,l1))) 3,利用內建函式匿名函式,將值大於10的留下來 l2 = [5,8,11,9,15] print(list(filter(lambda x:x > 10,l2))) 4,匿名函式可與三元運算結合 func = lambda x:x if x > 2 else x * 2
三、遞迴函式(自己呼叫自己)
1、人理解函式,神理解遞迴。
def func():
print(666)
func()
func()
結果:輸出一段時間後會報錯,因為
預設遞迴深度為998次,(官方給出的預設深度是1000,但實際上只有998次左右)
超過了就會報錯
2、引用模組修改遞迴次數
import sys
sys.setrecursionlimit(100000)
n = 1
def func(x):
print(x)
x += 1
func(x)
func(n)
結果:3222
雖然設定了100000次,但是電腦跑不起呀,
一般電腦就跑3222次左右,這個會根據電腦效能而定。
3、
小明比小白大兩歲 n = 4
小白比小狗大兩歲 n= 3
小狗比小紅大兩歲 n = 2
小紅24歲 n = 1
小明多少歲?
def age(n):
if n == 1:
return 24
else:
return age(n-1) + 2
age(4) # 30
詳解:
age(4)傳進引數n=4:
def age(4):
if n == 1:
return 24
else:
return age(4-1) + 2
結果:age(3)+2
def age(3):
if n == 1:
return 24
else:
return age(3-1) + 2
結果:age(2)+2+2
def age(2):
if n == 1:
return 24
else:
return age(2-1) + 2
結果:age(1)+2+2+2
def age(1):
if n == 1:
return 24
else:
return age(n-1) + 2
結果:age(1)+2+2+2 ---> 24+2+2+2--->30