一、遞歸函數
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
的錯誤。