Day10遞歸函數、模塊、迭代器、生成器

一、遞歸函數

1、什么是遞歸函數

在函數中調用函數本身的函數就是遞歸函數。

def func1():
    print('=======')
    func1()

func1()
2、遞歸的作用

循環能做的遞歸都能做

a = 0
def func2():
    global a
    if a < 3:
        print("aaa")
        a += 1
        func2()

func2()
3、怎么寫遞歸函數

第一步:確定臨界值 - 循環結束的條件,在臨界值的地方要讓函數結束!

第二步:找關系 - 找當次循環和上次循環的關系;

? 找f(n) 和 f(n-1)的關系

第三步:假設函數的功能已經實現,通過f(n-1)來實現f(n)的功能

例:求1+2+3+……+n

# 方法一:
n = 100
print(sum(range(n+1)))

# 方法二:
n = 100
sum1 = 0
for x in range(n+1):
    sum1 += x
print(sum1)

# 方法三:
def my_sum(n):
    # 1、找臨界值
    if n == 1:
        return 1
    # 2、找關系 my_sum(n)和my_sum(n-1)的關系
    # my_sum(n) : 1+2+3+...+n
    # my_sum(n-1) : 1+2+3+...+n-1
    # my_sum(n) = my_sum(n-1) + n
    return my_sum(n-1) + n
print(my_sum(100))

例:

def fab(n):
    if n == 1 or n == 2:
        return 1
    return fab(n-1) + fab(n-2)

print(fab(5))
4、循環能做的事情不要使用遞歸去做

遞歸的缺點:遞歸的可讀性比較低,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出。不建議使用。

二、模塊的使用

1、什么是模塊

在Python中一個py文件就是一個模塊。

a、系統模塊(標準庫) - Python系統提供的模塊

安裝解釋器的時候已經導入到解釋器中了,使用的時候在代碼中直接導入

import random # 提供隨機數的模塊
import math # 提供數學相關的方法模塊
import json # 提供json數據相關承操作庫
import re # 提供正則表達式相關操作
import sockey # 提供python套接字編程
import time # 提供時間相關方法
import threading #提供和線程相關操作
b、自定義模塊 - 程序員自己創建的py文件

自己寫的模塊

別人寫的模塊 - 第三方庫(需要先下載到解釋器中,然后才能在代碼中導入)

標準庫和第三方庫一般是通過模塊提供變量、函數、類

2、怎么使用模塊

import 模塊名

在程序中直接導入指定的模塊,導入后可以使用模塊中所有的全局變量。導入后通過“模塊名.變量”來使用模塊中的內容。

from 模塊名 import 變量1,變量2……

導入指定的模塊。導入后只能使用import后面的變量。導入后直接使用變量,不用在前面加'模塊名.'

from 模塊名 import *

將模塊中全部導入,并且可以直接使用里面所有的全局變量。

3、導入模塊的實質

a、不管是使用import還是from import,導入模塊的時候都會執行模塊中的所有代碼。

b、python中一個模塊不會重復導入多次,因為導入的時候系統會自動檢查當前模塊是否已經導入。

4、怎么阻止模塊中的內容被執行

寫在這個if語句中的代碼不會被別的模塊執行。

if __name__ == '__main__':

將不希望被其他模塊執行的代碼放在上面if語句中。如果希望被其他模塊使用的代碼就放在if語句外面。一般函數的聲明會放在if的外面。

原理:

每個模塊都有有個__name__屬性,代表模塊名。默認情況下它的值是py文件的文件名。當當前模塊正在被執行(直接執行)的時候,模塊屬性__name__的值就會變成'__main__'

5、重命名

導入模塊的時候可以對模塊或者模塊中的內容重新命名。

import 模塊名 as 新模塊名 # 重新命名新模塊名,原來的模塊名無法使用

from 模塊名 import name as new_name # 給模塊中的變量名重新命名

三、迭代器

1、什么是迭代器(iter)

是python提供的容器型數據類型。獲取迭代器元素的時候只能從前往后一個一個的取,而且取了之后這個元素在迭代器中就不存在了。

2、迭代器的字面量

迭代器沒有固定格式的字面量。

迭代器作為容器,里面的元素只能通過其他序列轉換或者生成器生成。

迭代器中的元素可以是任何類型的數據。

iter1 = iter('hello')
3、獲取元素

迭代器中的元素只支持查,不支持增刪改

迭代器是通過next函數獲取單個元素,for-in遍歷一個一個獲取每個元素。只要獲取的元素,元素在迭代器中就不存在了。

a、next
next(迭代器) # 獲取迭代器中最新的數據(最頂層)

例:

iter1 = iter('abc')
print(next(iter1)) # a
print(next(iter1)) # b
print(next(iter1)) # c

如果迭代器中的數據已經取完了,會報StopIteration 錯誤。

b、for-in
for x in iter1:
    print(x)

四、生成器

1、什么是生成器

生成器就是迭代器。迭代器不一定是生成器。

2、生成器怎么產生元素

調用一個帶有yield關鍵字的函數就能得到一個生成器。

不帶yield的函數(只看有沒有):調用的時候會執行函數體,并且獲取返回值

帶yield的函數:調用的時候不會執行函數體,也不會獲取返回值而是產生一個生成器(函數調用表達式就是一個生成器)

def func1():
    yield
print(func1()) # <generator object func1 at 0x00307F00>
3、生成器里面的元素

生成器中的元素也是通過next或者for-in來取。

生成器獲取元素,實質就是去執行生成器對應的函數,每次執行到yield語句為止,并且會將yield后面的值作為當次獲取到的元素。下次獲取元素的時候回接著上次結束的位置往后執行,直到下一個yield為止,以此類推,直到函數結束。

generator保存的是算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最后一個元素,沒有更多的元素時,拋出StopIteration的錯誤。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容