pythonic方式访问目录列表中的每个文件

时间:2014-03-27 14:25:12

标签: python

我的代码看起来像这样:

# Wow. Much nesting. So spacebar
if __name__ == '__main__:
  for eachDir in list_of_unrelated_directories:
      for eachFile in os.listdir(eachDir):
          if eachFile.endswith('.json'):
            # do stuff here

我想知道是否有更优雅的方式。我想不要让我的代码嵌套三层这样深,如果我能把它变成一个像

这样的单线程
for each file that ends with .json in all these directories:
  # do stuff

那会更加棒极了。我还编辑了这一点,指出目录不在同一个文件夹中。就像你可能在你的主文件夹和/ tmp文件夹中寻找.json文件一样。所以我并没有试图递归移动到一个文件夹。

5 个答案:

答案 0 :(得分:1)

您可以使用生成器表达式删除嵌套循环:

for json_file in (f for dir in list_of_unrelated_dirs 
                    for f in os.listdir(dir) 
                    if f.endswith('.json')):
    print json_file.

如果你想对它们应用一个函数,你甚至可以通过map()函数来删除剩余的for循环:

map(fun,
    (f for dir in list_of_unrelated_dirs 
       for f in os.listdir(dir) 
       if f.endswith('.json'))
)

希望这有帮助!

答案 1 :(得分:1)

当然,以下代码不是Pythonic ,因为它不是最简单或最清晰的代码,绝对不会遵循Zen of Python

然而,它是单行方法,这很有趣; - ):

def manage_file(filepath):
    print('File to manage:', filepath)

编辑:根据已接受的答案,我已更新了使用glob()的答案,结果仍然是 Freak code 但是它&#39 ;比我之前的方法更少的代码

map(manage_file, [fn for fn in sum((glob('%s/*.json' % eachDir) for eachDir in data_path), [])])

答案 2 :(得分:1)

最恐怖的方式是(在我看来)编写一个产生某种类型文件的函数并使用它。然后你的主叫代码非常清晰简洁。其他一些答案非常简洁但令人难以置信的混乱;在您的实际代码中,您应该重视清晰度而不是简洁(尽管当您可以获得两者时,当然,首选)。

这是功能:

import os

def files_from_directories(directories, filetype):
    """Yield files of filetype from all directories given."""
    for directory in directories:
        for file in glob.glob(os.path.join(directory, '*' + filetype))
            yield file

现在你的调用代码确实是一行代码:

# What a good one-liner!!!!
for json_file in files_from_directories(directories, '.json'):
    # do stuff

所以现在你有一个单行,一个非常清楚。此外,如果您要处理任何其他类型的文件,您只需重复使用不同文件类型的函数。

答案 3 :(得分:0)

glob()可以将您降低到两个级别:

for d in list_of_unrelated_directories:
    for f in glob(join(d, '*.json')):
         _process_json_file(f)

如果您的list_of_unrelated_directories 真的是一个完全不相关的目录列表,我看不出你怎么能避免第一个循环。
如果他们确实有一些共同点(比如说一个共同的根和一些公共前缀),然后你可以使用os.walk()遍历树并获取所有匹配的文件。

答案 4 :(得分:0)

它并没有真正的嵌套,它只是在理解中嵌套。

这会使所有以'.json'结尾的内容被确认为文件(忽略以'.json'结尾的文件夹。)

独立代码

import os

unrelated_paths = ['c:/', 't:/']
json_files = (os.path.join(p, o) for p in unrelated_paths
              for o in os.listdir(p)
              if (o.lower().endswith('.json')
                  and os.path.isfile(os.path.join(p, o))))
for json_file in json_files:
    print json_file