我在python中有一个函数,就像find
命令一样。所以基本上它会深入到m_depth
(maxdepth),如果在ignore_dirs
中指定,它将不会进入目录。它将返回walk
中找到的文件列表。代码非常简单并使用递归。
但是对于大量文件或更大的深度,递归花费时间并且返回时列表变得越来越大。所以无论如何我都在寻找发生器,所以至少每次迭代的内存消耗都会减少?
我尝试使用yield
结果,但只要找到ignore_dirs
就会退出。
这是我的代码:
def find(source_d, m_depth, ignore_dirs):
'''
This method does a recursive listing of files/directories from a given
path upto maximun recursion value provide as m_depth.
:param source_d: Given source path to start the recursion from
:param m_depth: Maximum recursion depth [determines how deep the method will traverse through the file system]
:param ignore_dirs: this paths will not be traversed. List of strings.
'''
def helper_find(path, ignore_dirs, m_depth, curr_depth=1):
files = []
if any(ignore_sub_dir == os.path.split(path)[-1] for ignore_sub_dir in ignore_dirs):
return []
if m_depth < curr_depth:
return []
else:
things = os.listdir(path)
for thing in things:
if(os.path.isdir(os.path.join(path, thing))):
files.extend(helper_find(os.path.join(path, thing), ignore_dirs, m_depth, curr_depth+1))
else:
files.append(os.path.join(path, thing))
return files
return helper_find(source_d, ignore_dirs, m_depth)
答案 0 :(得分:2)
答案是肯定的,你可以使用yield from
制作一个递归生成器(仅在Python 3中可用):
def find(source_d, m_depth, ignore_dirs):
'''
This method does a recursive listing of files/directories from a given
path upto maximun recursion value provide as m_depth.
:param source_d: Given source path to start the recursion from
:param m_depth: Maximum recursion depth [determines how deep the method will traverse through the file system]
:param ignore_dirs: this paths will not be traversed. List of strings.
'''
def helper_find(path, ignore_dirs, m_depth, curr_depth=1):
if not any(ignore_sub_dir == os.path.split(path)[-1] for ignore_sub_dir in ignore_dirs)and m_depth >= curr_depth:
things = os.listdir(path)
for thing in things:
if(os.path.isdir(os.path.join(path, thing))):
yield from helper_find(os.path.join(path, thing), ignore_dirs, m_depth, curr_depth+1)
else:
yield os.path.join(path, thing)
return helper_find(source_d, ignore_dirs, m_depth)