遞迴函式、演算法之二分法、三元表示式、各種生成式、匿名函式

吳仁耀發表於2023-03-02

一、遞迴函式

遞迴函式就是直接或間接呼叫函式自身的函式,當我們使用這種函式的時候,並不會出現預料之中的死迴圈,當迴圈次數達到1000左右就會被直譯器強行停止,雖然官方說是1000次,但是當我們使用時,通常會在996次左右停止,但是這種情況下的函式並不算遞迴函式,遞迴函式有以下兩個條件:

  • 1.直接或者間接呼叫自己

  • 2.每次呼叫都必須比上一次簡單,並且需要一個明確的結束條件

遞推:以層層往下

回溯:基於明確的結果一層層往上

# 虛擬碼:
"""
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18

age(n) = age(n-1)+2
age(1) = 20
"""


# 真實程式碼實現
def get_age(n):
    if n==1:
        return 18
    res=get_age(n-1)+2  # age(4)+2
    return res  # age(4)+2

print(age(5))

練習題:

# 利用遞迴函式依次列印列表中每一個資料值
l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
# 2.利用遞迴函式依次列印列表中每一個資料值
l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
"""
1.for迴圈l1裡面的資料值
2.如果是數字 則列印
3.如果是列表 則迴圈
4.for迴圈小列表裡面的資料值
5.如果是數字 則列印
6.如果是列表 則迴圈
7.for迴圈小小列表裡面的資料值
8.如果是數字 則列印
9.如果是列表 則迴圈
"""
# print(isinstance(123, int))  # 判斷第一個資料值是不是屬於第二個引數指定的資料型別
# print(isinstance(123, str))  # 判斷第一個資料值是不是屬於第二個引數指定的資料型別
def get_num(l1):
    for i in l1:  # 遞迴函式需要結束條件 這裡巧在for迴圈接收到空的能夠被for迴圈的資料時 自動不執行
        if isinstance(i,int):
            print(i)
        else:
            return get_num(i)

get_num(l1)

二、演演算法簡介之二分法

(1)、簡介

關於演演算法我們只需要稍微瞭解一下就可以了,對於演演算法,剛入行的小白基本是接觸不到相關工作的,除了頂尖高效的相關專業可以直接找到工作.通常情況下需要我們在進入一些公司工作一段時間後,被調到演演算法部門,才是正常的工作流程,對於演演算法這個東西,小公司不會成立相關部門研究演演算法,只有大公司才會成立部門研究演演算法,因為演演算法產出低,但是演演算法從業的工資又偏高,小公司中的演演算法部門大多數情況都是拿別人的演演算法來改用的

(2)、什麼是演演算法

演演算法的範圍很大,只要是解決問題的思路都算演演算法,但是不是所有的演演算法都是高效的,也有很多不合格的演演算法,可這並不影響演演算法的流行,因為演演算法的應用範圍確實很廣,幾乎涵蓋了我們生活中的方方面面,推薦演演算法(抖音影片推送、淘寶商品推送)、成像演演算法(AI相關)

常見演演算法的原理以及虛擬碼:

二分法、冒泡、快拍、插入、堆排、桶排、資料結構(連結串列 約瑟夫問題 如何連結串列是否成環)

(3)、二分法

二分法是演演算法中最簡單的演演算法,有很大缺陷,但是面試的時候喜歡拿來考一考

二分法有以下限制條件:

1.進行運算的資料值需要是有序的
2 .運算的時候如果需要取得的資料值是在開頭的,反而會更耗時

# 查詢列表中某個資料值
# 方式1:for迴圈  次數較多
# 方式2:二分法 不斷的對資料集做二分切割
correct = 754
# 假設我們要找到啊754這個值

# 獲取中間的索引,這裡透過整除來弄
def find(l1):
    # 如果列表中沒有資料值就說明查詢失敗了
    if len(l1) == 0:
        return '沒有找到'
    middle = len(l1) // 2
    if l1[middle] > correct:
        # 如果中間這個數的值大於要找的這個值就取列表左邊的列表繼續查詢
        new_list = l1[:middle]
        print(new_list)
        return find(new_list)
    elif l1[middle] < correct:
        # 如果中間這個數的值小於要找的這個值就取列表右邊的列表繼續查詢
        new_list = l1[middle:]
        print(new_list)
        return find(new_list)
    else:
        # 除了大於和小於兩種情況就是找到了那個值
        return correct


print(find(l1))

三、三元表示式

三元表示式本質

1.是對簡單的程式碼進行縮寫,簡單的來說就是偷懶的寫法減少程式碼行數

2.三元表示式只適合較為簡介的條件判定,較為複雜的判定建議不要用這種方式寫程式碼,因為比較讓人難以理解

3.三元表示式不建議巢狀使用,因為三元表示式是為了簡化程式碼,巢狀後反而看著更復雜了

三元表示式語法結構

資料值1 if 條件 else 資料值2
"""
條件成立則使用資料值1 條件不成立則使用資料值2
"""
a = 1
b = 10

c = 10
d = 20
res=a if a > b else (c if c > d else ( 'bbb' if d > c else 'aaa'))
print(res)

# is_beautiful=True
# res = '漂亮' if is_beautiful else '不漂亮'
# print(res)

cmd = input('請選擇是否輸入:(y/n)')
res='繼續' if cmd == 'y' else '不繼續'
print(res)

四、各種生成式

生成式總共有三種:列表生成式、字典生成式、集合生成式、集合生成式、元組沒有生成式,元組型別叫生成器,會生成一個類似工廠的東西,不會直接生成列表

生成式的作用:用於對資料型別中的所有資料值進行相同操作

表現形式:

new_list = [name + "_NB" for name in name_list]

左邊是變數名繫結修改後的結果,右邊最外層的是最後生成資料的型別,通常來說我們都是用的什麼生成器就在外層使用什麼型別對應的外層符號。內層for迴圈左邊的程式碼是規定進行的操作,for迴圈的作用就是一個個取值進行修改,因為外層套著框,所以修改後的值就依次儲存在列表中了,如果是字典和集合的話因為本身的無序性,輸出結果的時候可能會沒有順序。
列表生成式

name_list = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
# 給列表中所有人名的後面加上_NB的字尾
# for迴圈
new_list = []
for name in name_list:
    data = f'{name}_NB'
    new_list.append(data)
print(new_list)
# 列表生成式
# 先看for迴圈 每次for迴圈之後再看for關鍵字前面的操作
new_list = [name + "_NB" for name in name_list]
print(new_list)
# 複雜情況
new_list = [name + "_NB" for name in name_list if name == 'jason']
print(new_list)
new_list = ['大佬' if name == 'jason' else '小赤佬' for name in name_list if name != 'jack']
print(new_list)

字典生成式

# 字典生成式
s1 = 'hello world'
for i,j in enumerate(s1,start=100):
    print(i,j)
d1 = {i: j for i, j in enumerate('hello')}
print(d1)

注:這裡的i和j相當於進行了解壓賦值操作,如果這裡只有一個變數名,就等於繫結了一對鍵值對,這時候輸出的值就鍵值對,兩個變數的時候就是分別輸出鍵和值。
enumerate方法是給輸出的值輸出一個序號,可以自己設定起點的值

元組生成器(稍微介紹一下區別)
形式跟生成式差不多但是功能不一樣

# 元組生成式>>>:沒有元組生成式 下列的結果是生成器(後面講)
res = (i+'SB' for i in 'hello')
print(res)
for i in res:
    print(i)

五、匿名函式

# 沒有名字的函式
def index():
    pass

index()
"""
語法格式:
    lambda 形參:返回值
    lambda x:x**2

匿名函式一般步單獨使用,會配合其他函式使用
    map()
"""
# def index(x):
#     return x ** 2

# res=lambda x:x**2  # 記憶體地址
# print(res(2))
# # print(index(3))
#
# print(index)
# print(res)


l = [1,2,3,4,5,6,7,8,9]
# def index(x):
#     return x**2

# res=list(map(index, l))  # <map object at 0x0000017D935721F0>
res=list(map(lambda x:x**2, l))  # <map object at 0x0000017D935721F0>
print(res) # [1, 4, 9, 16, 25, 36, 49, 64, 81]

相關文章