简体   繁体   中英

Python list.remove(x) 2.7.5

I have two lists shown below. I'm trying to use the list.remove(x) function to remove the files that are in both list1 and list2, but one of my lists has file extensions while the other does not! What should be my approach!?

List1 = ['myfile.v', 'myfile2.sv', 'myfile3.vhd', 'etcfile.v', 'randfile.sv']
List2 = ['myfile', 'myfile2', 'myfile3']

#This is in short what I would like to do, but the file extensions throw off
#the tool!
for x in List2:
   List1.remove(x)

Thanks!

It's really dangerous to loop over a list as you are removing items from it. You'll nearly always end up skipping over some elements.

>>> L = [1, 1, 2, 2, 3, 3]
>>> for x in L:
...     print x
...     if x == 2:
...         L.remove(2)
... 
1
1
2
3
3

It's also inefficient, since each .remove is O(n) complexity

Better to create a new list and bind it back to list1

import os
list1 = ['myfile.v', 'myfile2.sv', 'myfile3.vhd', 'etcfile.v', 'randfile.sv']
list2 = ['myfile', 'myfile2', 'myfile3']
set2 = set(list2)  # Use a set for O(1) lookups
list1 = [x for x in list1 if os.path.splitext(x)[0] not in set2]

or for an "inplace" version

list1[:] = [x for x in list1 if os.path.splitext(x)[0] not in set2]

for a truly inplace version as discussed in the comments - doesn't use extra O(n) memory. And runs in O(n) time

>>> list1 = ['myfile.v', 'myfile2.sv', 'myfile3.vhd', 'etcfile.v', 'randfile.sv']
>>> p = 0
>>> for x in list1:
...     if os.path.splitext(x)[0] not in set2:
...         list1[p] = x
...         p += 1
... 
>>> del(list1[p:])
>>> list1
['etcfile.v', 'randfile.sv']

For the sake of it, if you want to use the list.remove(element) , as it is very easy to read for others, you can try the following. If you have a function f that returns true if the value is correct/passes certain tests as required,

Since this will NOT work:

def rem_vals(L):
    for x in L:
        if not f(x):
             L.remove(x)

for more than one value to be removed in the list L, we can use recursion as follows:

def rem_vals_rec(L):
    for x in L:
        if not f(x):
            L.remove(x)
            rem_vals_rec(L)

Not the fastest, but the easiest to read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM