Challenge:
change the code so that only .py and .txt files of a given directory are listed.

''' filename_list_given_dir1.py
use module glob to list all the filenames of .jpg files
or any extension(s) you specify in a given directory
'''

import glob
import os

# all files (split off file names) in a given directory
directory = "C:/Temp/*.jpg"
# this would give you all files
#directory = "C:/Temp/*.*"
for path in glob.glob(directory):
    #print(path)  # test
    # separate path from filename
    dirname, filename = os.path.split(path)
    print(filename)

Recommended Answers

All 14 Replies

Member Avatar for iamthwee

Would you change *.jpg to *.py

You can change *.jpg to *.py, but that won't show you the .txt files.

One idea, the result of glob.glob(path) is a list, so you could add the two lists
list_py_txt = glob.glob("c:/temp/*.py") + glob.glob("c:/temp/*.txt")

I would get rid of the glob.glob totally as we deal only with ends.

filenames = [path for path in os.listdir(directory) if path.endswith(('.py', '.txt'))]

Hm, os.listdir() returns names, one probably needs

filenames = [os.path.join(directory, name) for name in os.listdir(directory) if name.endswith(('.py', '.txt'))]

OP wanted only names and used os.path.split, which os.listdir makes unnecessary.

The nice thing about glob.glob() is that handles mixed case extensions like .Py or .TxT or .Txt that sometimes appear.

Would need to use the .lower() in addition to endswith to deal with that. And the file name should not really be called path.

filenames = [file_name for file_name in os.listdir(directory) if file_name.lower().endswith(('.py', '.txt'))]

Regex's anyone?

from re import search, I
from os import listdir

print [f for f in listdir('.') if search("\.py$|\.txt$", f, I) != None]

Regex's anyone?

I would use

r".*(?:\.py|\.txt)\Z(?ims)"

because glob uses fnmatch, which translates shell patterns into python regex, and this is how '.*' is translated:

>>> from fnmatch import translate
>>> translate('*.py')
'.*\\.py\\Z(?ms)'

I think it makes a difference if file names contain newline characters. The following works in my linux system, creating a file name containing newlines

>>> with open("foo\nbar.txt\n", "w") as ofh:
...  ofh.write('foobar')
... 
>>> 

your regex will list this file which does not end with .txt.

commented: good point! +7

I give it a try for fun.

#multi_glob.py
from glob import glob
import os

def multi_glob(path=None, *args):
    '''glob that can handle multiple file extensions option.
    #--- Usage ---#
    from multi_glob import multi_glob
    multi_glob(folder_path, '*.py', '*.txt')
    '''
    try:
        os.chdir(path)
    except OSError:
        os.chdir(os.getcwd())
        print 'Wrong path using script(.py) folder path'
    f_lst = []
    for files in args:
        f_lst.extend(glob(files))
    return f_lst

Test:

>>> from multi_glob import multi_glob
>>> print multi_glob(r'C:\temp999', '*.py', '*.txt')
Wrong path using script(.py) folder path
['02252014-162200.709116.txt', 'saladsfilecost.txt']

>>> print multi_glob(r'C:\temp', '*.py', '*.txt')
['micc.py', 'module9.py', 'tid_delta_csv.py', 'pass.txt', 'VRayLog.txt']

>>> help(multi_glob)
Help on function multi_glob in module __main__:

multi_glob(path=None, *args)
    glob that can handle multiple file extensions option.
    #--- Usage ---#
    from multi_glob import multi_glob
    multi_glob(folder_path, '*.py', '*.txt')

os.chdir(os.getcwd())

This is a no-op :)

This is a no-op :)

Yes i can agree with that :)

#multi_glob.py
from glob import glob
import os

def multi_glob(path=None, *args):
    '''glob that can handle multiple file extensions option.
    #--- Usage ---#
    from multi_glob import multi_glob
    multi_glob(folder_path, '*.py', '*.txt')
    '''
    try:
        os.chdir(path)
    except OSError:
        return 'Wrong folder path,try again'
    f_lst = []
    for files in args:
        f_lst.extend(glob(files))
    return f_lst

Test:

>>> from multi_glob import multi_glob
>>> print multi_glob(r'C:\temp', '*.py', '*.txt')
['micc.py', 'module9.py', 'tid_delta_csv.py', 'pass.txt', 'VRayLog.txt']
>>> print multi_glob(r'C:\temp999', '*.py', '*.txt')
Wrong folder path,try again

Here a version of iglob,that can take multiple file extensions.

#iter_glob
from glob import iglob
from itertools import chain
import os, sys

def iter_glob(path=None, *args):
    '''A iglob version that return an iterator fully lazy evaluated
     and can handle multiple file extensions.
    #--- Usage ---#
    from iter_glob import iter_glob
    for filename in multi_glob(folder_path, '*.py', '*.txt'):
        print filename
    '''
    try:
        os.chdir(path)
    except Exception as error:
        print 'Wrong folder path {},try again'\
        .format(str(error).split(':',1)[-1].strip())
        sys.exit()
    return chain.from_iterable(iglob(pattern) for pattern in args)

Test:

>>> from iter_glob import  iter_glob
>>> for filename in iter_glob(r'C:\temp', '*.py', '*.txt'):
...     print filename
...     
micc.py
module9.py
tid_delta_csv.py
pass.txt
VRayLog.txt

>>> for filename in iter_glob(r'C:\temp999', '*.py', '*.txt'):
...     print filename
...     
Wrong folder path 'C:\\temp999',try again
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.