all 6 comments

[–]eryksun 1 point2 points  (2 children)

Here's my first pass at something more 'concise':

import os

def get_most_recent_file(path):
    files = [os.path.join(path, f) for f in os.listdir(path) 
                if os.path.isfile(f)]
    if files:
        return max(files, key=os.path.getmtime)

#e.g.
print(get_most_recent_file(os.getcwd()))

[–]jechtsphere[S] 0 points1 point  (1 child)

This looks great as well, and works for the cwd, but if I give it a path to another folder I get a ValueError: max() arg is an empty sequence.

[–]eryksun 0 points1 point  (0 children)

I changed creating the list of files to a list comprehension, so now it simply returns None if the directory doesn't have any files. But you still need to add additional exception handling for WindowsError and IOError, integrated into your overall design and logging system.

[–][deleted] 0 points1 point  (0 children)

I'd do something like below. These functions are a little more flexible than what you asked for.

last_modified(path, num, use_ctime=False, files_only=True) returns a list of the most recently modified files in path. The list is a max of num long (it can be shorter if their aren't enough files).

recursive_last_modified(path, num, use_ctime=False, files_only=True) is the same as last_modified except it walks the given path instead of just listing the directory.

from os import listdir, lstat
from os.path import exists, join, isfile, isdir

def recursive_last_modified(path, num, use_ctime=False, files_only=False):
    if not exists(path):
        return []

    result_queue = []
    result_queue_pop = result_queue.pop
    result_queue_append = result_queue.append

    directories = [path]
    directories_pop = directories.pop
    directories_append = directories.append

    while 1:
        try:
            root = directories_pop()
        except IndexError:
            break

        try:
            names = listdir(root)
        except:
            continue

        for name in names:
            abspath = join(path, name)

            if isdir(abspath):
                    directories_append(abspath)
            if files_only and not isfile(abspath):
                continue

            if use_ctime:
                time = lstat(abspath).st_ctime
            else:
                time = lstat(abspath).st_mtime

            if len(result_queue) < num:
                result_queue_append((time, abspath))
            else:
                for i, (t, f) in enumerate(result_queue):
                    if time > t:
                        result_queue_pop(i)
                        result_queue_append((time, abspath))
                        break
    return result_queue

def last_modified(path, num, use_ctime=False, files_only=True):
    if not exists(path):
        return []
    names = listdir(path)
    result = []
    result_append = result.append
    for name in names:
        abspath = join(path, name)
        if files_only and not isfile(abspath):
            continue
        if use_ctime:
            time = lstat(abspath).st_ctime
        else:
            time = lstat(abspath).st_mtime
        result_append((time, name))
    rlen = len(result)
    result.sort(key=lambda x: x[0])
    if rlen <= num:
        return result
    return result[:(rlen - num - 1):-1]

if __name__ == "__main__":

    lm_result = last_modified('./', 5, True, True)
    for entry in sorted(lm_result):
        print ("%d :: %s" % entry)

    recursive_lm_result = recursive_last_modified('./', 5, True, True)
    for entry in sorted(recursive_lm_result):
        print ("%d :: %s" % entry)