2016-07-11 18 views
0

Also was ich suche ist die richtige Art, eine Liste zu suchen und die Elemente basierend auf mehreren anderen Listen zu filtern.Brauchen Sie Hilfe bei Listencomprehensions. Wie man mehrere Ausschlüsse verwendet

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.'] 

Ich möchte dann über meine Imagelist und Filter incuded_extensions und dann in excluded_textures angegeben alle Textur Abkürzungen mit nur Bilder iterieren auszufiltern.

Mein Code fehlgeschlagen:

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

Das Ergebnis sollte dann nur

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

'[ich für i in imagelist wenn any (ext in i für ext in enthalten) und nicht irgendwelche (ext in i für ext in ausgeschlossen)]'? – Bakuriu

+5

Sie wären besser dran, indem Sie dies als Standard-Nested-Loops schreiben, * dann * versuchen, das Listenverständnis daraus zu erstellen (wenn Sie das Gefühl haben, dass Sie das brauchen). – jonrsharpe

+0

Übrigens, nur weil etwas * als * Listenverstehen geschrieben werden kann, heißt das nicht, dass * es * als Listenverständnis geschrieben werden sollte. Lesbarkeit zählt! – DeepSpace

Antwort

2

In diesem Fall enthalten, würde ich eine Schleife verwenden - Cramming sie alle in einer einzigen Liste Verständnis ist würde den Code schwerer verständlich zu machen, was nicht wirklich ist, was Sie wollen ...:

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) 

ich habe es gerade getestet ein d Dieser Code gibt die richtige Ausgabe.

+0

Können Sie erklären, warum Sie die __included_extensions__ von 'list' in' tuple' geändert haben? Ist das mit der Geschwindigkeit verbunden? –

+0

Upvote für sauberen Code .. Können Sie erklären, wie die letzte if-Anweisung funktioniert? –

+1

@ Ev.Kounis - 'str.startswith' und' str.endswith' akzeptieren 'tuple' (aber nicht' liste'). – mgilson

1
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) 
0
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'] 

Wenn Sie wirklich dieses Verständnis mit Liste tun möchte, ist hier, wie. (Nicht sehr gut lesbar)

+0

FWIW, 'any (img.endswith (good_ext) für good_ext in included_extensions) kann als' img.endswith (tuple (included_extensions)) 'geschrieben werden und wenn' included_extensions' ein 'tuple' ist, dann ist es definitiv einfacher schreiben. – mgilson

+0

Vielen Dank! Wiederum kommt Stack Overflow zur Rettung! – NaughtyDag

Verwandte Themen