空序列的功能失败

时间:2017-06-18 11:49:04

标签: python

我试图根据我在本网站上无耻地发现的一些Python代码,找到目录中最新文件的日期。

def newest_file_in_tree(rootfnewer, extension=".avi"):
    return max(
        (os.path.join(dirname, filename)
        for dirname, dirnames, filenames in os.walk(rootfnewer)
        for filename in filenames
        if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime)

这可行,但在空目录上失败。

    key=lambda fn: os.stat(fn).st_mtime)
ValueError: max() arg is an empty sequence

我承认我是一名Python初学者,最后一行超出了我的工资等级。

任何人都可以建议我如何捕获错误并防止函数崩溃?

2 个答案:

答案 0 :(得分:7)

maxdefault个关键字:

m = max([], key=lambda x: abs(x), default='empty...')
print(m) # 'emtpy...'

如果iterable为空,将返回default。没有default,这会引发ValueError

另一种方法是使用glob列出文件:

import os
from glob import glob

def newest_file_in_tree(rootdir, ext='.avi'):
    glob_wildcard = os.path.join(rootdir, '**/*{}'.format(ext))
    glob_gen = glob(glob_wildcard, recursive=True)
    return max(glob_gen, key=lambda fn: os.stat(fn).st_mtime, default='?')

或更简洁pathlib

from pathlib import Path

def newest_file_in_tree(rootpath, ext='.avi'):
    return max(Path(rootpath).glob('**/*{}'.format(ext)),
               key=lambda pth: pth.stat().st_mtime, default='?')

答案 1 :(得分:4)

你可以将那个怪异的pythonic单行分隔成两个单独的行,以确保只有当你有一个非空的文件列表时才调用max,你可以从中挑选最新的一行:

def newest_file_in_tree(rootfnewer, extension=".avi"):
    files = [
        os.path.join(dirname, filename)
        for dirname, dirnames, filenames in os.walk(rootfnewer)
        for filename in filenames
        if filename.endswith(extension)
    ]

    if files:
        return max(files, key=lambda fn: os.stat(fn).st_mtime)

    return None

不像@ hiroprotagonist的解决方案那么漂亮,但更具可读性。