remove a list from a list

Rares Vernica rvernica at gmail.com
Fri Nov 17 18:42:12 EST 2006


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




More information about the Python-list mailing list