我有两个列表如下所示。我正在尝试使用list.remove(x)函数来删除list1和list2中的文件,但我的一个列表有文件扩展名而另一个没有!我的方法应该是什么!?
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)
谢谢!
答案 0 :(得分:8)
当您从列表中删除项目时,循环遍历列表真的很危险。你几乎总是会跳过某些元素。
>>> L = [1, 1, 2, 2, 3, 3]
>>> for x in L:
... print x
... if x == 2:
... L.remove(2)
...
1
1
2
3
3
效率也很低,因为每个.remove
都是O(n)复杂度
最好创建一个新列表并将其绑定回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]
或“inplace”版本
list1[:] = [x for x in list1 if os.path.splitext(x)[0] not in set2]
对于评论中讨论的真正的原位版本 - 不使用额外的O(n)内存。并在O(n)时间内运行
>>> 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']
答案 1 :(得分:0)
为此,如果您想使用list.remove(element)
,因为它很容易为其他人阅读,您可以尝试以下方法。如果你有一个函数f,如果值正确则返回true /根据需要通过某些测试,
因为这不起作用:
def rem_vals(L):
for x in L:
if not f(x):
L.remove(x)
要在列表L中删除多个值,我们可以使用递归,如下所示:
def rem_vals_rec(L):
for x in L:
if not f(x):
L.remove(x)
rem_vals_rec(L)
不是最快的,但最容易阅读。