實例中學習python的walk/map/filter/lambda

jopen 10年前發布 | 14K 次閱讀 Python 機器學習

背景

編程語言只有在實際使用中才能積累實戰經驗,才能真正掌握。從尋找特定文件夾中尋找特定后綴名的文件列表是一個很常用的場景,可以擴展到將找到的(符合條件的)文件列表做重命名、刪除、備份等操作。我們本次就從此實例出發,去學習python語言中的walk/map/filter/lambda函數的使用。

我們測試環境的當前目錄下除了兩個代碼文件:jsj_xx_1.py和jsj_xx_2.py,其余都是測試相關的目錄和文件,具體如下:


實例的需求是找到當前目錄下的后綴名為“.name1”和“.name2”的文件。開始吧,搞懂我們的示例代碼(2個.py文件),就大致就掌握了walk/map/filter/lambda這些函數啦

我們分別使用os.path.walk和os.walk去實現,學習這兩個看似很混淆的函數。

使用os.path.walk

使用os.path.walk的話,我們計算機學習微信公眾號:jsj_xx的代碼(jsj_xx_1.py)如下:(請參考注釋)

import os

# author: jsj_xx

def find_filter_files(dir_list, name):

# 保存結果的列表,用于輸出

found_file_list = []


# 對指定目錄(dirname)處理,該目錄下的文件和子目錄都在list_of_dir列表里,

處理(包括過濾子目錄和過濾一些文件)后的結果保存到found_file_list里 </p>

# 0)使用lambda定義一個簡單的合成完整路徑的匿名函數,其中a就是list_of_dir中的元素

# 1)map用來將list_of_dir列表里的所有元素加上完整路徑名

# 2)第二個filter用來過濾掉所有的子目錄

# 3)第一個filter用來過濾掉不符合后綴名條件的文件

# 4)最后通過extend將符合條件的文件存放到found_file_list列表里

def filter_name_func(found_file_list, dirname, list_of_dir):

found_file_list.extend(\

filter(lambda a: os.path.splitext(a)[1] in name,\

filter(os.path.isfile,\

map(lambda a: os.path.join(dirname, a), list_of_dir))))


def func(one_dir):

# path.walk對一個目錄做處理,

對該目錄下的每個子目錄和文件都會調用

filter_name_func做處理,

對目錄的每個子目錄又會遞歸如上的處理。 </p>

os.path.walk(one_dir, filter_name_func, found_file_list)


# 遍歷dir_list列表,以每一個元素(比如dir1目錄)

作為入參去調用函數func </p>

map(func, dir_list)

return found_file_list


if __name__ == '__main__':

print "found files: "+" ".join(find_filter_files(['dir1','dir2'], [".name1", ".name2"]))

</blockquote>

運行結果:(找出dir1和dir2兩個目錄下的后綴名為“.name1”或者“.name2”的文件

jsj_xx$ python jsj_xx_1.py
found files: dir1/1.name1 dir2/2.name2

</blockquote>

下面是pydoc對os.path.walk的講解:

walk(top, func, arg)

Directory tree walk with callback function.

For each directory in the directory tree rooted at top (including top

itself, but excluding '.' and '..'), call func(arg, dirname, fnames).

dirname is the name of the directory, and fnames a list of the names of

the files and subdirectories in dirname (excluding '.' and '..').

</blockquote>

可見,對于示例代碼中的filter_name_func,它里面的dirname是當前處理的目錄(比如“dir1”或者“dir2/dir3”)。而list_of_dir則是該目錄下的所有文件和子目錄('.'和’..'除外),沒有做區分

使用os.walk

如果使用os.walk,我們計算機學習微信公眾號:jsj_xx的代碼(jsj_xx_2.py)如下:(請參考注釋)

import os

# author: jsj_xx

def find_filter_files(dir,name):

found_file_list = []

# 將每個需要處理的目錄(parent_dirname)下的文件和子目錄區分對待

# 文件列表存放到list_of_dir里,子目錄列表存放在dirname里

# 其它部分代碼參考jsj_xx_1.py即可

for parent_dirname,dirname,list_of_dir in os.walk(dir):

found_file_list.extend(\

filter(lambda a: os.path.splitext(a)[1] in name,\

filter(os.path.isfile,\

map(lambda a: os.path.join(parent_dirname, a), list_of_dir))))


return found_file_list


if __name__ == '__main__':

print "found files: "+" ".join(find_filter_files('.',['.name1', '.name2']))

</blockquote>

運行結果:(找出當前目錄下的后綴名為“.name1”或者“.name2”的文件

jsj_xx$ python jsj_xx_2.py
found files: ./dir1/1.name1 ./dir2/2.name2

</blockquote>

下面是pydoc對os.walk的講解:

walk(top, topdown=True, onerror=None, followlinks=False)

Directory tree generator.

For each directory in the directory tree rooted at top (including top

itself, but excluding '.' and '..'), yields a 3-tuple

dirpath, dirnames, filenames

dirpath is a string, the path to the directory. dirnames is a list of

the names of the subdirectories in dirpath (excluding '.' and '..').

filenames is a list of the names of the non-directory files in dirpath.

Note that the names in the lists are just names, with no path components.

To get a full path (which begins with top) to a file or directory in

dirpath, do os.path.join(dirpath, name).

</blockquote>

可見,對于示例代碼中的os.walk,parent_dirname是處理的目錄,dirname是其下的所有子目錄('.'和’..'除外),而list_of_dir則是其下的所有文件,(對parent_dirname目錄下的文件和子目錄)做了區分

總結

os.path.walk沒有對處理目錄下的文件和子目錄做區分,直接交給回調函數處理(內部可以再去區分),而os.walk是區分的。另外,os.path.walk是不需要循環迭代每個目錄(通過循環迭代回調函數來隱式實現),而os.walk需要顯式循環迭代每個目錄。通過實例,我們也大致掌握了map/filter/lambda函數的用法

來自:http://mp.weixin.qq.com/s?__biz=MzAxNjM3MDkyOQ==&mid=205165830&idx=1&sn=de5010c54f96b5ea0a456a41d1603c30

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!