我的代码看起来像这样:
# 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文件一样。所以我并没有试图递归移动到一个文件夹。
答案 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