1. 程式人生 > 實用技巧 >三元表示式,列表、字典、集合生成式,生成器表示式,函式遞迴,匿名函式,面向過程程式設計

三元表示式,列表、字典、集合生成式,生成器表示式,函式遞迴,匿名函式,面向過程程式設計

一、三元表示式,列表、字典、集合生成式,生成器表示式

1、三元表示式

三元表示式是python為我們提供的一種簡化程式碼的解決方案,優雅的取代雙分支if。語法如下

res = 條件成立時返回的值 if 條件 else 條件不成立時返回的值

針對下述場景

def max2(x,y):
    if x > y:
        return x
    else:
        return y
res = max2(1,2)

用三元表示式可以一行解決

x=1
y=2
res = x if x > y else y # 三元表示式

2、列表生成式

列表生成式是python為我們提供的一種簡化程式碼的解決方案,用來快速生成列表,語法如下

案例一
l = []
for i in range(10):
    l.append(i)
print(l)
用列表生成式可以一行解決
l = [i for i in range(10)]

案例二
l = []
for i in range(10):
    if i > 5:
        l.append(i)
print(l)
用列表生成式可以一行解決
l = [i for i in range(10) if i > 5]

案例三
names = ["lxx",'hxx',"wxx",'lili']   #如果每個人的名字後面加'_sb'
l = [name + "_sb" for name in names]

案例四
names = ["egon","lxx_sb","hxx_sb","wxx_sb"]    #取有'_sb'的值
res = [name for name in names if name.endswith("sb")]

3、字典生成式

res = {i: i ** 2 for i in range(5)}
print(res)  #生成字典

items = [('k1',111),('k2',222),('k3',333)]
   print(dict(items))
或 print({k:v for k,v in items}) #生成字典

4、集合生成式

res = {i for i in range(5)}
print(res)

5、生成器表示式

建立一個生成器物件有兩種方式,一種是呼叫帶yield關鍵字的函式,另一種就是生成器表示式,與列表生成式的語法格式相同,只需要將[]換成(),即:

res = (i for i in range(3))
如果我們要讀取一個大檔案的位元組數,應該基於生成器表示式的方式完成
with open('db.txt','rb') as f:
    nums=(len(line) for line in f)
    total_size=sum(nums) # 依次執行next(nums),然後累加到一起得到結果=
with open('a.txt',mode='rt',encoding='utf-8') as f:
    res = f.read()
    print(len(res))
    
    res = 0
    for line in f:
        res += len(line)
        
    res = sum((len(line) for line in f))
    res = sum(len(line) for line in f)
 
    print(res)

二、函式遞迴

1、函式遞迴呼叫

是函式巢狀呼叫的一種特殊形式,函式在呼叫時,直接或間接呼叫了自身,就是遞迴呼叫,本質就是一個迴圈的過程

#1、遞迴呼叫應該包含兩個明確的階段:回溯,遞推
    回溯就是從外向裡一層一層遞迴呼叫下去,
        回溯階段必須要有一個明確地結束條件,每進入下一次遞迴時,問題的規模都應該有所減少(否則,單純地重複呼叫自身是毫無意義的)
     遞推就是從裡向外一層一層結束遞迴
大前提:遞迴呼叫一定要在某一層結束

2、示例
age(5) = age(4) + 10
age(4) = age(3) + 10
age(3) = age(2) + 10
age(2) = age(1) + 10
age(1) = 18

def age(n):
    if n == 1:
        return 18
    return age(n-1) + 10

res = age(5)
print(res)
函式遞迴取值
nums = [1,[2,[3,[4,[5,[6,[7,]]]]]]]
def get(l):   
	for num in l:      
    	if type(num) is list:       
    		get(num)       
   		 else:            
  		  print(num)
get(nums)

python中的遞迴效率低且沒有尾遞迴優化

#python中的遞迴
python中的遞迴效率低,需要在進入下一次遞迴時保留當前的狀態,在其他語言中可以有解決方法:尾遞迴優化,即在函式的最後一步(而非最後一行)呼叫自己,尾遞迴優化:http://egon09.blog.51cto.com/9161406/1842475
但是python又沒有尾遞迴,且對遞迴層級做了限制

#總結遞迴的使用:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少
3. 遞迴效率不高,遞迴層次過多會導致棧溢位(在計算機中,函式呼叫是通過棧(stack)這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函式返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的次數過多,會導致棧溢位)

2、二分法

想從一個按照從小到大排列的數字列表中找到指定的數字,遍歷的效率太低,用二分法(演算法的一種,演算法是解決問題的方法)可以極大低縮小問題規模

nums = [-3,1,3,7,13,23,37,43,57,63,77,91,103]  #從小到大排列
find_num = 64
def find(nums,find_num):
    print(nums)
    if len(nums) == 0:
        print("not exists")
        return
    mid_index = len(nums) // 2
    if find_num > nums[mid_index]:
        # in the right
        find(nums[mid_index+1:],find_num)
    elif find_num < nums[mid_index]:
        # in the left
        find(nums[:mid_index], find_num)
    else:
        print('you got it')
find(nums,find_num)

三、匿名函式

概念

匿名就是沒有名字的函式。特點:臨時用一次
def func(x,y,z=1):
    return x+y+z

匿名
lambda x,y,z=1:x+y+z #與函式有相同的作用域,但是匿名意味著引用計數為0,使用一次就釋放,除非讓其有名字
func=lambda x,y,z=1:x+y+z 
func(1,2,3)
#讓其有名字就沒有意義

有名字的函式與匿名函式的對比

#有名函式與匿名函式的對比
有名函式:迴圈使用,儲存了名字,通過名字就可以重複引用函式功能

匿名函式:一次性使用,隨時隨時定義

應用:max,min,sorted,map,reduce,filter

四、面向過程程式設計

#1、首先強調:面向過程程式設計絕對不是用函式程式設計這麼簡單,面向過程是一種程式設計思路、思想,而程式設計思路是不依賴於具體的語言或語法的。言外之意是即使我們不依賴於函式,也可以基於面向過程的思想編寫程式

#2、定義
面向過程的核心是過程二字,過程指的是解決問題的步驟,即先幹什麼再幹什麼

基於面向過程設計程式就好比在設計一條流水線,是一種機械式的思維方式

#3、優點:複雜的問題流程化,進而簡單化

#4、缺點:可擴充套件性差,修改流水線的任意一個階段,都會牽一髮而動全身

#5、應用:擴充套件性要求不高的場景,典型案例如linux核心,git,httpd

#6、舉例
流水線1:
使用者輸入使用者名稱、密碼--->使用者驗證--->歡迎介面

流水線2:
使用者輸入sql--->sql解析--->執行功能