os.listdir() not showing contents of directory - python

Here is my code:
files = [f for f in os.listdir(os.getcwd() + "\\folder") if os.path.isfile(f)]
for file in files:
print("hello")
I am running this from the directory which contains a folder called "folder". This folder has 4 files in it. This should print "hello" four times in my head - but it doesn't.
What have I misunderstood?
PS Do I need to use os.getcwd() here? I figure it would be cleaner to just use a relative path, but that also doesn't work.

With os.path.isfile(f) you're asking if f is a file inside your current directory, not inside folder. Replace your code with:
[f for f in os.listdir(os.path.join(os.getcwd(), "folder")) if os.path.isfile(os.path.join("folder", f))]
I've also taken the liberty of using os.path.join to avoid direct concatenation of file and folder names as strings, since slashes can be a bit iffy.
And for the record, no you don't need to use os.getcwd() here (but I left it there anyways).

Related

Python: Understanding os.listdir() Method

I am still a beginner with python and I would like to understand what the following code does.
files = [f for f in os.listdir('E:/figs/test') if os.path.isfile(f)]
imgs = []
#read input
for f in files:
if 'jpg' in f and 'background' not in f:
imgs.append(cv2.imread(f))
print(imgs)
As it can be seen, I have inserted a path to the folder containing the images. However, when I print the content, it is empty. Please, could anyone explain what could be the reason as well as the way for solving it?
It's because os.path.isfile(f) is checking whether f is a file; but f is under E:/figs/text. What you should try is the following:
main_dir = "E:/figs/test"
files = [f for f in os.listdir(main_dir) if os.path.isfile(os.path.join(main_dir, f))]
As this will check the existence of the file f under E:/figs/text.
os.listdir() method in python is used to get the list of all files and directories in the specified directory. If we don’t specify any directory, then list of files and directories in the current working directory will be returned.
You have to use // instead of / in your folder path
Like this:
files = [f for f in os.listdir('E://figs//test') if os.path.isfile(f)]
Try this it may run

How to print the names of files from a folder?

I'm trying to print the names of all the files from a folder directory. I have a folder called "a", and in that folder there are 3 NC files, lets call them "b","c","d", whose directory I want to print. How would I do this?
For example, given my path to the folder is
path=r"C:\\Users\\chz08006\\Documents\\Testing\\a"
I want to print the directories to all the files in the folder "a", so the result should print:
C:\\Users\\chz08006\\Documents\\Testing\\a\\b.nc
C:\\Users\\chz08006\\Documents\\Testing\\a\\c.nc
C:\\Users\\chz08006\\Documents\\Testing\\a\\d.nc
So far, I've tried
for a in path:
print(os.path.basename(path))
But that doesn't seem to be right.
I think you're looking for this:
import os
path = r"C:\\Users\\chz08006\\Documents\\Testing\\a"
for root, dirs, files in os.walk(path):
for file in files:
print("{root}\\{file}".format(root=root, file=file))
You can have a list of file names in a folder using listdir().
import os
path = "C:\\Users\\chz08006\\Documents\\Testing\\a"
l = os.listdir(path)
for a in l:
print(path + a)
You made a couple mistakes. You were using os.path.basename, that only returns the name of the file or folder represented at the end of a path after the last file separator.
Instead, use os.path.abspath to get the full path of any file.
The other mistake was one of using the wrong variable inside the loop (print(os.path.basename(path) instead of using the variable a)
Also, dont forget to use os.listdir to list the files inside the folder before looping.
import os
path = r"C:\Users\chz08006\Documents\Testing\a"
for file in os.listdir(path): #using a better name compared to a
print(os.path.abspath(file)) #you wrote path here, instead of a.
#variable names that do not have a meaning
#make these kinds of errors easier to make,
#and harder to spot

python: file paths no longer work with imp

I recently started using imports to better organize my code in python. My original code in file1.py used the line:
def foo():
files = [f for f in os.listdir('.') if os.path.isfile(f)]
print files
#do stuff here....
Which referenced all the files in the same folder as the code, print files showing the correct output as an array of filenames.
However, I recently changed the directory structure to something like this:
./main.py
./folder1/file1.py
./folder1/data_file1.csv
./folder1/data_file2.csv
./folder1/......
And in main.py, I use:
import imp
file1 = imp.load_source('file1', "./folder1/file1.py")
.
.
.
file1.foo()
Now, files is an empty array. What happened? I have tried absolute filepaths in addition to relative. Directly declaring an array with data_file1.csv works, but I can't get anything else to work with this import.
What's going on here?
When you do os.listdir('.') , you are trying to list the contents of '.' (which is the current directory) , but this does not need to be the directory in which the script resides, it would be the directory in which you were in when you ran the script (unless you used os.chdir() inside the python script).
You should not depend on the current working directory , instead you can use __file__ to access the path of the current script, and then you can use os.path.dirname() to get the directory in which the script resides.
Then you can use os.path.join() to join the paths of the files you get from os.listdir() with the directory of the script and check if those paths are files to create your list of files.
Example -
def foo():
filedir = os.path.dirname(__file__)
files = [f for f in (os.path.join(filedir, fil) for fil in os.listdir(filedir)) if os.path.isfile(f)]
print files
#do stuff here....

Finding last modified date of files with special extensions

I have written the Python script below to find the last modified date of a file:
for root, dirs, files in os.walk(folder_path):
for f in files:
last_modified = datetime.fromtimestamp(os.path.getmtime(f)).day
#do something
This code works fine for normal files like .txt files. However, if it encounters files with extensions like .tar.gz or .run, it throws an error saying "No such file or directory" when finding last_modified.
* EDIT *
I realized that, if I change the code as below, it works fine.
for f in files:
name = os.path.join(root, f)
last_modified = datetime.fromtimestamp(os.path.getmtime(name)).day
#do something
But why does this happen?
os.walk return filenames relative to the folder it is walking. E.g. if it is walking a directory called foo with a file called bar, it will return bar, not foo/bar. However, since your script (presumably) is not in the folder os is walking, it needs an absolute path, or a path relative to itself. Therefore, you must join the folder path to the filename, so that python can find the file.
As the docs say:
Note that the names in the lists contain no path components. To get a full path (which begins with top) to a file or directory in dirpath, do os.path.join(dirpath, name).
Why it happens to work with the text files I'm not sure. Do you have text files with the same name in the folder containing your script?

Python script errors out

I have this script, which I have no doubt is flawed:
import fnmatch, os, sys
def findit (rootdir, find, pattern):
for folder, dirs, files in os.walk(rootdir):
print (folder)
for filename in fnmatch.filter(files,pattern):
with open(filename) as f:
s = f.read()
f.close()
if find in s :
print(filename)
findit(sys.argv[1], sys.argv[2], sys.argv[3])
when I run it I get Errno2, no such file or directory. BUT the file exists. For instance if I execute it by going: findit.py c:\python "folder" *.py it will work just fine, listing all the *.py files which contain the word "folder". BUT if I go findit.py c:\php\projects1 "include" *.php
as an example I get [Errno2] no such file or directory: 'About.php' (for example). But About.php exists. I don't understand what it's doing, or what I'm doing wrong.
If you look at any of the examples for os.walk, you'll see that they all do os.path.join(root, name). You need to do that too.
Why? Quoting from the docs:
filenames is a list of the names of the non-directory files in dirpath. Note that the names in the lists contain no path components. To get a full path (which begins with top) to a file or directory in dirpath, do os.path.join(dirpath, name).
If you just use the filename as a path, it's going to look for a file of the same name in the current working directory. If there's no such file, you'll get a FileNotFoundError. If there is such a file, you'll open and read the wrong file. Only if you happen to be looking inside the current working directory will it work.
There's also another major problem in your code: os.walk walks a directory tree recursively, finding all files in the given top directory, or any subdirectory of top, or any subdirectory of… and so on, yielding once for each directory. But you're not doing anything useful with that (except printing out the folders). Instead, you wait until it finishes, and then use the files from whichever directory it happened to reach last.
If you just want to get a flat listing of the files directly in a directory, use os.listdir, not os.walk. (Or maybe use glob.glob instead of explicitly listing everything then filtering with fnmatch.)
On the other hand, if you want to walk the tree, you have to move your second for loop inside the first one.
You've also got a minor problem: You call f.close() inside a with open(…) as f:, which leads to f being closed twice. This is guaranteed to be completely harmless (at least in 2.5+, including 3.x), but it's still a bad idea.
Putting it together, here's a working version of your code:
def findit (rootdir, find, pattern):
for folder, dirs, files in os.walk(rootdir):
print (folder)
for filename in fnmatch.filter(files,pattern):
pathname = os.path.join(folder, filename)
with open(pathname) as f:
s = f.read()
if find in s:
print(pathname)
You are using a relative filename. But your current directory does not contain the file. And you don't want to search there anyway. Use os.path.join(folder, filename) to make an absolute path.

Categories