2017-12-15 12 views
2

私はfindコマンドのように動作するPythonの関数を持っています。だから、基本的には、0123,(最大深度)に達するまで深く入り、ignore_dirsで指定されていれば、ディレクトリには入りません。 walkにあるファイルのリストを返します。コードは本当にシンプルで、再帰を使います。osでジェネレータを使うにはwrapperのような関数を見つけるのですか?

しかし、ファイルの数が多い場合や深さが深い場合は、再帰に時間がかかり、復帰時にリストが大きくなります。とにかく、ジェネレータを使用できるかどうかを探していますので、メモリ消費量はatleastごとに少なくなります。

私は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) 

答えて

2

答えはイエスである、あなたは(だけのPython 3で利用可能)yield fromを使用して再帰的な発電を行うことができます。

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) 
+0

'伴う問題any(ignore_sub_dir in path ... 'は' videos'ディレクトリに行きたくないと仮定していますので、 'ignore_dirs'を' [videos "、" some "]'として渡します。ソースパス*の下にある 'videos'に行きます*のみ*ソースパス自体に' videos'が含まれているとどうなりますか?最初のステップでは戻ります。私のポイントを得ています...私はさまざまなシナリオのために私のコードをユニットテストしましたが、私はバグはありませんでした。 –

+0

あなたのコードをチェックしてお知らせします! –

+0

テストケースを投げ捨てている余分な空のリストが返ってきます。余分な空のリストを返すことはできますか? –

関連する問題