This solution I think is pretty nice: source[:] = [x for x in source if x.lower() not in target]
Thanks a lot for all the answers, Ray Steven D'Aprano wrote: > On Fri, 17 Nov 2006 12:00:46 -0800, Rares Vernica wrote: > >> Problem context: >> >> import os >> dirs_exclude = set(('a', 'b', 'e')) >> for root, dirs, files in os.walk('python/Lib/email'): >> # Task: >> # delete from "dirs" the directory names from "dirs_exclude" >> # case-insensitive >> >> The solution so far is: >> >> for i in xrange(len(dirs), 0, -1): >> if dirs[i-1].lower() in dirs_exclude: >> del dirs[i-1] >> >> I am looking for a nicer solution. > > Define "nicer". > > First thing I'd do is change the loop: > > for i in xrange(len(dirs)-1, -1, -1): > if dirs[i].lower() in dirs_exclude: > del dirs[i] > > Second thing I'd do is encapsulate it in a function instead of calling it > in place: > > def remove_in_place(source, target): > for i in xrange(len(source)-1, -1, -1): > if source[i].lower() in target: > del source[i] > > Third thing I'd do is replace the delete-in-place code away, and build a > new list using the set idiom, finally using list slicing to change the > source in place: > > def remove_in_place2(source, target): > target = set(s.lower() for s in target) > source[:] = [x for x in source if x.lower() not in target] > # note the assignment to a slice > > And finally, I would test the two versions remove_in_place and > remove_in_place2 to see which is faster. > > > import timeit > > setup = """from __main__ import remove_in_place > target = list("aEIOu") > source = list("AbcdEfghIjklmnOpqrstUvwxyz") > """ > > tester = """tmplist = source[:] # make a copy of the list! > remove_in_place(tmplist, target) > """ > > timeit.Timer(tester, setup).timer() > > You have to make a copy of the list on every iteration because you are > changing it in place; otherwise you change the values you are testing > against, and the second iteration onwards doesn't have to remove anything. > > > (All code above untested. Use at own risk.) > -- http://mail.python.org/mailman/listinfo/python-list