the-bax
the-bax

Reputation: 5

how to retrieve the most recent file from a folder in python

I'm trying to retrieve the most recent file added or modified in a directory. The code i got on one of the forums use the method below:

import os

filelist = os.listdir('MYDIRECTORY')
filelist = filter(lambda x: not os.path.isdir(x), filelist)
newest = max(filelist, key=lambda x: os.stat(x).st_mtime)

i put my directory there and it gives me the following error:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    newest = max(filelist, key=lambda x: os.stat(x).st_mtime)
  File "test.py", line 8, in <lambda>
    newest = max(filelist, key=lambda x: os.stat(x).st_mtime)
OSError: [Errno 2] No such file or directory: 'NAME OF FILE'

with the name of the newest file shown above. So it is finding the file, but what could be the problem. Please help

Upvotes: 0

Views: 1763

Answers (3)

J David Smith
J David Smith

Reputation: 4810

The problem is that os.listdir returns file names, not paths. While it may seem that the next command (filtering on os.path.isdir) works given just the name, you should note that isdir returns False when no object exists with that name.

What you need to do is combine the path with the file names:

import os

dirname = 'MYDIRECTORY'
filenames = os.listdir(dirname)
filepaths = [os.path.join(dirname, filename) for filename in filenames]
files = [f for f in filepaths if not os.path.isdir(f)]
newest = max(files, key=lambda x: os.stat(x).st_mtime)

Note that I replaced the filter call with a list comprehension. This is considered more 'Pythonic' (eww), but I did it because list comprehensions are typically faster than filter/map in Python.

Upvotes: 0

Mike DeSimone
Mike DeSimone

Reputation: 42805

  1. Instead of not os.path.isdir(x) you should use os.path.isfile(x).

  2. filter is deprecated; list comprehensions are preferred:

    filelist = [f for f in filelist if os.path.isfile(f)]
    
  3. os.listdir just gives you the names of the items in the directory, not full paths. To get full paths, you need to do something like os.path.join('MYDIRECTORY', f).

So all fixed up it should look like:

import os

rootpath = 'MYDIRECTORY'
filelist = [os.path.join(rootpath, f) for f in os.listdir(rootpath)]
filelist = [f for f in filelist if os.path.isfile(f)]
newest = max(filelist, key=lambda x: os.stat(x).st_mtime)

Upvotes: 2

ntki
ntki

Reputation: 2304

os.listdir() does not include the directory you are listing in the paths that are returned. So you either have to os.chdir("MYDIRECTORY") into it before you call os.stat(x), or prepend the name of the directory like os.stat("MYDIRECTORY/" + x).

Or chdir into it beforehand and use listdir on the current directory like os.listdir(".").

Upvotes: 0

Related Questions