亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎么在遞歸函數中使用迭代器

發布時間:2021-09-29 09:02:28 來源:億速云 閱讀:136 作者:小新 欄目:開發技術

小編給大家分享一下Python怎么在遞歸函數中使用迭代器,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

首先,想要實現的功能是遞歸遍歷文件夾,遇到滿足條件的文件時,用yield返回該文件的位置。

如果不用遞歸器,可以這樣實現:

path_list = []
def get_one_cage(root: str, cook_folder_name: str):
    for item in os.listdir(root).copy():
        item_path = os.path.join(root, item)
        if item == cook_folder_name:
            path_list.append(item_path)
            return
        elif os.path.isdir(item_path):
            get_one_cage(item_path, cook_folder_name)

即,深度優先遍歷,滿足要求時,將item_path補充到列表里,之后返回上一層。
這里有一個問題,需要有一個列表,把所有滿足條件的地址全存起來,占內存。

使用迭代器可以用一個,遍歷出來一個,省內存

替換為迭代器,最先想到的是,把 return 換成 yield,使用for循環調用迭代器函數

def get_one_cage(root: str, cook_folder_name: str):
    for item in os.listdir(root).copy():
        item_path = os.path.join(root, item)
        if item == cook_folder_name:
            yield item_path
        elif os.path.isdir(item_path):
            get_one_cage(item_path, cook_folder_name)

但是這樣的程序跑到內嵌函數時,進不去,我百思不得其解

現在看,應該是因為迭代器函數不是一個函數,不是一個命令語句,它只是一個對象。

簡單說就是,python程序一般遵循:動詞+名詞的結構,或者動詞,比如:

a = 1

這句話實際上是把1賦值給了a,是有動詞的。
迭代器只是一個名詞,必須用for語句調用或者next()方法調用才會執行,或者是print,yield,return等等,反正得加個動詞,不能孤零零一個名詞。
而且上述代碼還有一個漏洞。在第一段代碼中,我們用一個全局變量存放遍歷結果。在第二段代碼里,我們本意是把結果yield到for循環調用的地方,但事實是,程序已經套了好幾層了,每次yiled只能返回一層。如下圖所示:

Python怎么在遞歸函數中使用迭代器

綜上兩點作出如下修改:

def get_one_cage(root: str, cook_folder_name: str):
    for item in os.listdir(root).copy():
        item_path = os.path.join(root, item)
        if item == cook_folder_name:
            yield item_path
        elif os.path.isdir(item_path):
            yield get_one_cage(item_path, cook_folder_name)

程序執行結果如下:

Python怎么在遞歸函數中使用迭代器

顯然是返回了一個迭代器,不是一個str,其邏輯如下圖所示:

Python怎么在遞歸函數中使用迭代器

就好比,本意是:
小明把沙袋傳給小紅,小紅傳給小蘭
但現在是:
小明把沙袋傳給了小紅,小紅被傳了出去
修改如下:

def get_one_cage(root: str, cook_folder_name: str):
    for item in os.listdir(root).copy():
        item_path = os.path.join(root, item)
        if item == cook_folder_name:
            yield item_path
        elif os.path.isdir(item_path):
            yield next(get_one_cage(item_path, cook_folder_name))

邏輯如下:

Python怎么在遞歸函數中使用迭代器

還有一種情況是學長源碼里的:使用for調用迭代器:

def get_one_cage(root: str, cook_folder_name: str):
    for item in os.listdir(root).copy():
        item_path = os.path.join(root, item)
        if item == cook_folder_name:
            yield item_path
        elif os.path.isdir(item_path):
             for i in get_one_cage(item_path, cook_folder_name):
                 yield i

這使用于多個文件的返回,源碼里還配合isfile使用,這里是簡化版,所以顯得冗余。
兩種方式均可以正常使用。

昨天這篇文章寫完后,遇到了bug,簡單說就是,如果一個文件夾系統沒有我們想要的文件,遞歸到最深一層文件夾時,會報錯

Python怎么在遞歸函數中使用迭代器

1
可以理解為:老板讓員工找一樣東西,員工外包給編外人員。如果編外人員找到了想要的東西,一路傳遞回去,可以正常交差。如果沒找到,編外人員就會一直找,不停歇,找遍了所有能找到的地方(遍歷完整個文件夾)也沒能找到,就會報錯StopIteration。
因此,問題核心是,沒有一個返回機制。修改辦法是在遍歷最后加一個空返回

def get_one_cage(root: str):
    for index, item in enumerate(os.listdir(root)):
        item_path = os.path.join(root, item)
        if item == 'cooked_xyz':
            yield item_path
        elif os.path.isdir(item_path):
            yield next(get_one_cage(item_path))
        elif index == len(os.listdir(root).copy()) - 1:
            yield

或者是利用try… except語句處理異常:

def get_one_cage(root: str):
    try:
        for item in os.listdir(root):
            item_path = os.path.join(root, item)
            if item == 'cooked_xyz':
                yield item_path
            elif os.path.isdir(item_path):
                yield next(get_one_cage(item_path))
    except:
        yield

Python怎么在遞歸函數中使用迭代器

會有如上報錯,正常。
最后的yield換成return也是可以的,但最好還是用yield,兩個混起來用怪怪的。

個人推薦第二種方法
注:copy()可以不用要

以上是“Python怎么在遞歸函數中使用迭代器”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

崇阳县| 获嘉县| 克什克腾旗| 措勤县| 磐安县| 池州市| 灵宝市| 东辽县| 遵义县| 锦州市| 通海县| 白山市| 平舆县| 都安| 十堰市| 博湖县| 岳西县| 五指山市| 昭觉县| 襄汾县| 齐河县| 鄄城县| 商河县| 梅州市| 永福县| 津南区| 中宁县| 平利县| 文山县| 吴旗县| 滨州市| 巴林左旗| 昌乐县| 柘城县| 宿迁市| 井陉县| 兰坪| 张家界市| 桐柏县| 施秉县| 通州区|