mmagician
mmagician

Reputation: 2120

If condition on list elements within list comprehension

I would like to know whether it's possible to replace this:

results = [x for x in os.listdir(dir_path) if os.path.splitext(x)[1] == ".tif" and "abc" in os.path.splitext(x)[0]]

with something like:

results = [x for x in os.listdir(dir_path) if ext == ".tif" and "abc" in name for ext, name in os.path.splitext(x)]

Thanks for help

Upvotes: 0

Views: 180

Answers (3)

Eric Villarba
Eric Villarba

Reputation: 56

I am guessing that this is what you want:

results = [name + ext for name, ext in [os.path.splitext(x) for x in os.listdir(dir_path)] if ext == ".tif" and "abc" in name ]

Note: I have placed name before ext.

And the internal list is generating a list of tuples that is the name and ext value.

Upvotes: 1

tobias_k
tobias_k

Reputation: 82949

You can define name and ext using an inner generator expression:

results = [x for x, name, ext in ((x, *os.path.splitext(x)) for x in os.listdir(dir_path))
             if ext == ".tif" and "abc" in name]

Here, *os.path.splitext(x) unpacks the result of that call to the name and ext variables in the outer list comprehension (only in Python 3). For older versions, you can use (x,) + os.path.splitext(x) instead. Also note that splitext will return a tuple (name, ext), not (ext, name).

Alternatively, instead of using splitext, just check the filename directly, assuming that the part you want to find in the name part can not appear in the extension part of the file name.

results = [x for x in os.listdir(dir_path) if x.endswith(".tif") and "abc" in x]

Upvotes: 1

Feodoran
Feodoran

Reputation: 1822

Your line is quite long, you might want to split it into multiple lines. You could wrap your condition in a function:

def filter_file(path):
    ext, name = os.path.splitext(path)
    if not ext == '.tif':
        return False
    return 'abc' in name

And then use

results = [x for x in os.listdir(dir_path) if filter_file(x)]

Upvotes: 3

Related Questions