What's the best way, both aesthetically and from a performance perspective, to split a list of items into multiple lists based on a conditional? The equivalent of:
good = [x for x in mylist if x in goodvals]
bad = [x for x in mylist if x not in goodvals]
is there a more elegant way to do this?
Update: here's the actual use case, to better explain what I'm trying to do:
# files looks like: [ ('file1.jpg', 33L, '.jpg'), ('file2.avi', 999L, '.avi'), ... ]
IMAGE_TYPES = ('.jpg','.jpeg','.gif','.bmp','.png')
images = [f for f in files if f[2].lower() in IMAGE_TYPES]
anims = [f for f in files if f[2].lower() not in IMAGE_TYPES]
Sometimes you won't need that other half of the list. For example:
Sometimes, it looks like list comprehension is not the best thing to use !
I made a little test based on the answer people gave to this topic, tested on a random generated list. Here is the generation of the list (there's probably a better way to do, but it's not the point) :
And here we go
Using the cmpthese function, the best result is the dbr answer :
If you insist on clever, you could take Winden's solution and just a bit spurious cleverness:
I think a generalization of splitting a an iterable based on N conditions is handy
For instance:
If the element may satisfy multiple conditions, remove the break.
Already quite a few solutions here, but yet another way of doing that would be -
Iterates over the list only once, and looks a bit more pythonic and hence readable to me.