0

With Python 3.7.7, I want to get the list of all the images that don't end with *_mask.tif.

In the path there are images that end with *.tif and with *_mask.tif. But the following code returns all of them.

# Read all the brain images (those that don't end with _mask.tif).
def brain_images_list(path):
    if not isinstance(path, str):
        raise TypeError('path must be a string')

    if not os.path.exists(path):
        raise ValueError('path must exist: ', path)

    if not os.path.isdir(path):
        raise ValueError('path must be a directory: ', path)

    # Save current directory.
    current_dir = os.getcwd()

    # Change current directory to the one we want to look for.
    os.chdir(path)

    # Get brain images list
    brain_images_lst = glob.glob('*.tif')

    # Restore directory
    os.chdir(current_dir)

    return brain_images_lst

How can I do it?

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • in ```brain_images_lst = glob.glob('*.tif')``` you're getting all the images. You need to filter out those that you don't want. – ewokx Aug 04 '20 at 07:35
  • Yes, I know what I have to do, my problem is that I don't know how to do it. – VansFannel Aug 04 '20 at 07:36
  • 2
    `brain_images_lst = [image for image in brain_images_lst if not image.endswith("_mask.tif")]`? – UnholySheep Aug 04 '20 at 07:38
  • 1
    Does this answer your question? [glob exclude pattern](https://stackoverflow.com/questions/20638040/glob-exclude-pattern) – UnholySheep Aug 04 '20 at 07:42

4 Answers4

3

You are making it complicated for yourself with the use of glob.glob and the need to change directory, do the glob, and change back again.

If you just want the filenames (not full paths), you will be better to use os.listdir, which can be done without changing directory:

brain_images_lst = [file for file in os.listdir(path)
                    if file.endswith(".tif")
                    and not file.endswith("_mask.tif")]
alani
  • 12,573
  • 2
  • 13
  • 23
2

You better get yourself used to using pathlib whenever working with paths. It is better than using os.path in most cases, and your specific task can be easily done by doing:

from pathlib import Path

brain_images_lst = [file for file in Path(path).glob("*.tif") if not file.stem.endswith("mask")]

The glob returns Path objects so if you just want the names of the files you can change to file.name.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • 1
    Nice, I like it. One little thing: this makes a list of `PosixPath` objects, which might be useful as-is, but to match the existing output format (a list of filenames) it could be worth doing instead `[file.name for file in ....]` – alani Aug 04 '20 at 08:15
  • @alaniwi I totally agree. Check-out my note under the code ;) – Tomerikoo Aug 04 '20 at 08:56
  • Good point -- not sure how I missed that :) – alani Aug 04 '20 at 10:02
0

* is a wildcard for glob. So asking to get *.tif will also return *_mask.tif. To only get *.tif you will want to first store the list as you are but then create a list of all *_mask.tif. The following code does this

brain_images_lst2 = glob.glob('*_mask.tif')

using this we can then remove all *_mask.tif from the *.tif by using a loop as such:

for x in brain_images_lst2:
    brain_images_lst.remove(x)

This should then cause brain_images_lst to only contain *.tif as required.

The Grand J
  • 348
  • 2
  • 5
  • 14
0

Try this:

First list all files with tif type in file_list

Store only files in result list which don't _mask.tif

import glob

result = []
file_list= glob.glob(r'C:\Users\vishal\Desktop\Stackoverflow\*.tif') 
for file in file_list:
    if  '_mask.tif' in file:
        continue
    result.append(file)
print(result)
Vishal Upadhyay
  • 781
  • 1
  • 5
  • 19