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

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")

Jump to Post

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'))]
Jump to Post

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'))]
Jump to Post

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 …

Jump to Post

All 14 Replies

Re: Python Challenges 80 80

Would you change *.jpg to *.py

Re: Python Challenges 80 80

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

Re: Python Challenges 80 80

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")

Re: Python Challenges 80 80

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'))]
Re: Python Challenges 80 80

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'))]
Re: Python Challenges 80 80

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

Re: Python Challenges 80 80

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

Re: Python Challenges 80 80

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'))]
Re: Python Challenges 80 80

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]
Re: Python Challenges 80 80

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
Re: Python Challenges 80 80

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')
Re: Python Challenges 80 80

os.chdir(os.getcwd())

This is a no-op :)

Re: Python Challenges 80 80

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
Re: Python Challenges 80 80

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 1.19 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.