0

我有两个列表如下所示。我正在尝试使用 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)

谢谢!

4

2 回答 2

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]

或“就地”版本

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']
于 2013-07-02T00:41:29.597 回答
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)

不是最快的,但最容易阅读。

于 2016-07-12T13:01:28.770 回答