day11-日常(遞歸函數(shù)、模塊、迭代器、生成器)

遞歸函數(shù)(實際開發(fā)的時候,能不用遞歸就不用)

1.什么是遞歸函數(shù)

函數(shù)中調(diào)用函數(shù)本身的函數(shù)就是遞歸函數(shù)

2.遞歸的作用:循環(huán)能做的事情遞歸函數(shù)都能做

例如:

# 先確定函數(shù)遞歸出口
def func2():
    global a
    if a < 5:
        print('~~~~~')
        a += 1
        func2()
"""
func2()
~~~~~
0 < 5:  a = 1   func2()
~~~~~
1 < 5    a = 2   func2()
~~~~~
2 < 5    a = 3   func2()
~~~~~
3 < 5    a = 4   func2()
~~~~~    
4 < 5    a = 5   func2()
~~~~~   
5 < 5   
""" 

3.怎么寫遞歸函數(shù):f(n)

  • 第一步:確定臨界值 - 循環(huán)結(jié)束的條件,在臨界值的地方要讓函數(shù)結(jié)束!
  • 第二步:找關(guān)系 - 找當次循環(huán)和上次循環(huán)的關(guān)系;找f(n)和f(n-1)的關(guān)系
  • 第三步:假設(shè)函數(shù)f的功能已經(jīng)實現(xiàn),通過f(n-1)來實現(xiàn)f(n)的功能
    """

練習(xí):實現(xiàn):1+2+3+...+n

  • a.for循環(huán)
n = 20
sum1 = 0
for x in range(n+1):
    sum1 += x
print(sum1)
  • b.遞歸
    注意:循環(huán)能做的事情不能使用遞歸做!
def my_sum(n):
    # 1.找臨界值
    if n == 1:
        return 1

    # 2. 找關(guān)系
    """
    找my_sum(n)和my_sum(n-1)的關(guān)系
    my_sum(n): 1+2+3+...+n-1+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(4))
print(my_sum(100))
print(my_sum(1000)) # 會報錯,python中對于遞歸,有最大遞歸深度

執(zhí)行過程:

my_sum(4):
n = 4   4==1   return my_sum(3)+4  ---> return 1+2+3+4
my_sum(3):
n = 3   3==1   return my_sum(2)+3  ---> return 1+2+3
my_sum(2):
n = 2   2==1   return my_sum(1)+2  ---> return 1+2
my_sum(1):
n = 1   1==1   return 1

練習(xí): 求斐波那契數(shù)列第n個數(shù):1, 1, 2, 3, 5, 8, 13....(用遞歸函數(shù))

def sequence(n):
    # 1.找臨界值
    if n == 1 or n == 2:
        return 1
    # 2. f(n)和f(n-1)
    """
    f(n) = f(n-1)+f(n-2)
    """
    return sequence(n-1)+sequence(n-2)

print(sequence(5))

模塊

1.什么是模塊

在python中一個py文件就是一個模塊

  • a.系統(tǒng)模塊(標準庫) - python系統(tǒng)提供的模塊(安裝解釋器的時候已經(jīng)導(dǎo)入到解釋器中了,使用的時候在代碼中直接導(dǎo)入)

    • random模塊 - 提供隨機數(shù)
    • math模塊 - 提供數(shù)學(xué)運算
    • json庫 - 提供json數(shù)據(jù)相關(guān)操作
    • re模塊 - 提供正則表達式相關(guān)操作
    • socket模塊 - 提供python套接字編程
    • time模塊 - 提供和時間相關(guān)的操作
    • threading模塊 - 提供和線程相關(guān)的操作
    • ...
  • b.自定義模塊 - 程序員自己創(chuàng)建的py文件

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

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

2.怎么使用模塊

import 模塊名   - 在程序中直接導(dǎo)入指定的模塊, 導(dǎo)入后可以使用模塊中所有的全局變量(包含了變量、函數(shù)和類)
                 導(dǎo)入后通過"模塊名.變量"來使用模塊中的內(nèi)容  

方法一:

from 模塊名 import 變量1, 變量2  -  在程序中導(dǎo)入指定的模塊,導(dǎo)入后只能使用import后面的變量
                                  導(dǎo)入后直接使用變量,不用在前面加'模塊名.'

方法二:

from 模塊名 import * - 在程序中直接導(dǎo)入指定的模塊, 導(dǎo)入后可以使用模塊中所有的全局變量(包含了變量、函數(shù)和類)
                      導(dǎo)入后直接使用變量,不用在前面加'模塊名.'

3.導(dǎo)入模塊的實質(zhì):

  • a.不管是使用import還是from-import,導(dǎo)入模塊的時候都會執(zhí)行模塊中所有的代碼
  • b.python中一個模塊不會重復(fù)導(dǎo)入多次。因為導(dǎo)入的時候系統(tǒng)會自動檢查當前模塊是否已經(jīng)導(dǎo)入

4.怎么阻止模塊中的內(nèi)容被其他模塊執(zhí)行

  • a.將不希望被其他模塊執(zhí)行的代碼放在if語句中
  • b.如果希望被其他模塊使用的代碼就放在if語句的外碼
  • (這兒的if語句指的是: if name == 'main')

原理:每個模塊都有一個name屬性, 代表模塊名。默認情況下它的值是py文件的文件名。
當當前模塊正在被執(zhí)行(直接執(zhí)行)的時候,模塊屬性name的值就會變成main

5.重命名 - 導(dǎo)入模塊的時候可以對模塊或者模塊中的內(nèi)容重新命名

  • import 模塊名 as 新模塊名
  • from 模塊名 import 變量名1 as 新變量名1, 變量名2, 變量名3 as 新變量名3

示例:

import threading as TD
name = 100

from model4 import name as my_name, age as my_age

print(name)
print(my_name)
print(my_age)

迭代器

1.什么是迭代器(iter)

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

2.迭代器的字面量

迭代器沒有指定格式的字面量。迭代器作為容器,里面的元素只能通過其他序列轉(zhuǎn)換,或者通過生成器生成
迭代器中的元素可以是任何類型的數(shù)據(jù)

示例:

# 將字符串轉(zhuǎn)換成迭代器,迭代器中的元素就是字符串中的每個字符
iter1 = iter('hello')
print(iter1)

# 將列表轉(zhuǎn)換成迭代器,迭代器中的元素就是列表中的每個元素
iter2 = iter([100, 'shj', (10, 20), [1, 2], True, {'name': '小花'}, lambda x: x])
print(iter2)

3.獲取元素

  • (迭代器中的元素只支持查,不支持增刪改)
  • 迭代器是通過next函數(shù)獲取單個元素,for-in遍歷一個一個獲取每一個元素。
  • 不管哪種方式獲取,已經(jīng)獲取過的元素,在迭代器中就不存在

示例:

iter3 = iter('hello')

# 1.next
"""
next(迭代器)  -> 獲取迭代器中最新的數(shù)據(jù)(最頂層)
"""
print(iter3)
print(next(iter3))
print(next(iter3))
print(next(iter3))
print(next(iter3))
print(next(iter3))
# print(next(iter3))   # 報 'StopIteration'異常, 因為在這兒迭代器中的數(shù)據(jù)已經(jīng)取完了
print(iter3)

iter3 = iter('123456')
print(next(iter3))

# 通過for-in取迭代器中的元素和next效果一樣,元素還是會從迭代器中取出
for x in iter3:
    print('x:', x)
# print(next(iter3))

練習(xí): 看打印結(jié)果

iter4 = iter([10, True, 'abc', (1, 2)])

index = 0
for x in iter4:
    index += 1
    if index == 2:
        break

item = next(iter4)
print(item)
print(next(iter4))

生成器

1.什么是生成器

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

2.生成器怎么產(chǎn)生元素

調(diào)用一個帶有yield關(guān)鍵字的函數(shù)就能得到一個生成器

  • 不帶yield的函數(shù): 調(diào)用的時候會執(zhí)行函數(shù)體,并且獲取返回值
  • 帶yield的函數(shù):調(diào)用的時候不會執(zhí)行函數(shù)體,也不會獲取返回值,而是產(chǎn)生一個生成器(函數(shù)調(diào)用表達式就是一個生成器)。這個生成器中的元素就是yield關(guān)鍵字后面的值

示例:

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


print(func1())  # 100


def func2():
    if False:
        yield
    print('@@@@@@@')
    return 100



print(func2())   # <generator object func2 at 0x1054f6200>

3.生成器的元素

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

生成器獲取元素,實質(zhì)就是去執(zhí)行生成器對應(yīng)的函數(shù), 每次執(zhí)行到y(tǒng)ield語句為止,并且會將yield后面的值作為當次獲取到的元素;
下次獲取元素的時候會接著上次結(jié)束的位置往后執(zhí)行,直到下一個yield為止....
以此類推,直到函數(shù)結(jié)束。如果執(zhí)行到函數(shù)結(jié)束沒有遇到y(tǒng)ield那么就會報'StopXXXXX'異常
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容