user6551558
user6551558

Reputation:

Need help on list comprhensions. How to use several exclusions

So what I'm looking for is the correct way to search a list and filter the items based on several other lists.

imageList = ['green_D.jpg', 'red_D.gif', 'orange_R.jpg', 'black_S.gif', 'folder_A', 'folder_B']
included_extensions = ['jpg', 'bmp', 'png', 'gif']
excluded_textures = ['_R.', '_A.', '_S.']

I want to then iterate over my imageList and filter only images using incuded_extensions and then filter out all texture abbreviations specified in excluded_textures.

My failed code:

newImageList = [ (img for img in imageList) if (tex for tex in excluded_textures) not in img and any(img.endswith(ext) in img for ext in included_extensions)]

The result should then only contain

newImageList = ['green_D.jpg', 'red_D.gif']

Upvotes: 0

Views: 79

Answers (3)

mgilson
mgilson

Reputation: 310227

In this case, I'd use a loop -- Cramming it all into a single list-comprehension is going to make the code harder to understand which isn't really what you want...:

imageList = ['green_D.jpg', 'red_D.gif', 'orange_R.jpg', 'black_S.gif', 'folder_A', 'folder_B']
included_extensions = ('jpg', 'bmp', 'png', 'gif')  # Note, tuple.
excluded_textures = ('_R.', '_A.', '_S.')

newImageList = []
for img in imageList:
    # If the extension isn't included, just continue the loop.
    if not img.endswith(included_extensions):  # str.endswith accepts tuple, but not list (see change above).
        continue

    # Split off the extension so we can test the excluded_textures
    base, _ = os.path.splitext(img)
    # If the image's base ends with an excluded texture, just continue the loop.
    if (base + '.').endswith(excluded_textures):
        continue

    # The image has passed all of the validation we threw at it.  Add
    # it to the newImageList.
    newImageList.append(img)

I've just tested it and this code gives the correct output.

Upvotes: 2

Dean Fenster
Dean Fenster

Reputation: 2395

In [16]: new_list = [img for img in imageList if any(img.endswith(good_ext) for 
    ...: good_ext in included_extensions) and not any(bad_tex in img for bad_tex
    ...:  in excluded_textures)]

In [17]: new_list
Out[17]: ['green_D.jpg', 'red_D.gif']

If you really want to do this with list comprehension here's how. (Not very readable)

Upvotes: 0

Joran Beasley
Joran Beasley

Reputation: 114088

imageList = ['green_D.jpg', 'red_D.gif', 'orange_R.jpg', 'black_S.gif', 'folder_A', 'folder_B']
included_extensions = ['jpg', 'bmp', 'png', 'gif']
excluded_textures = ['_R.', '_A.', '_S.']

print filter(lambda x:x[-3:] in included_extensions and x[-6:-3] not in excluded_textures,imageList)

Upvotes: 1

Related Questions