0

我想从列表 A 中删除列表 B 中的列表项。这是我编写的函数:

def remove(A,B): 

    to_remove=[];
    for i in range(len(A)):
        for j in range(len(B)):
            if (B[j]==A[i]):
                to_remove.append(i);

    for j in range(len(to_remove)):
        A.pop(to_remove[j]);

这是正常的做法吗?虽然,这完全没问题(如果拼写错误,我不知道),我认为可能有更多的pythonic方式来做到这一点。请建议。

4

4 回答 4

5

转换Bset第一个,然后A使用列表推导创建一个新数组:

s = set(B)
A = [item for item in A if item not in s]

集合中的项目查找是一种O(1)操作。

如果您不想更改id()of A,则:

A[:] = [item for item in A if item not in s]
于 2013-10-15T18:30:44.350 回答
2

列出对救援的理解:

[item for item in A if item not in B]

然而,这会创建一个新列表。您可以从函数返回列表。

或者,如果您可以在 list 中丢失任何重复项A,或者没有重复项,则可以使用set差异:

return list(set(A) - set(B))

一个警告是,这不会保留A. 所以,如果你想要元素有序,这不是你想要的。请改用第一种方法。

于 2013-10-15T18:29:33.240 回答
2

列表理解呢?

def remove(removeList, fromList):
    return [x for x in fromList if x not in removeList]

此外,为了让生活更轻松并更快地删除,您可以从 list 制作一个集合removeList,只留下独特的元素:

def remove(removeList, fromList):
    removeSet = set(removeList)
    return [x for x in fromList if x not in removeSet]

>>> print remove([1,2,3], [1,2,3,4,5,6,7])
[4, 5, 6, 7]

而且,当然,您可以使用内置filter函数,尽管有人会说它不是 Python 的,您应该使用列表生成器。不管怎样,这里有一个例子:

def remove(removeList, fromList):
    removeSet = set(removeList)
    return filter(lambda x : x not in removeSet, fromList)
于 2013-10-15T18:31:23.893 回答
2

首先,请注意您的功能无法正常工作。尝试这个:

A = [1, 2, 3]
B = [1, 2, 3]
remove(A, B)

您将获得, 因为每次执行. 时IndexError要删除的正确索引都会更改.pop()

毫无疑问,您会得到建议使用集合的答案,如果数组元素是可散列且可比较的,那确实会好得多,但通常您可能需要这样的东西:

def remove(A, B):
    A[:] = [avalue for avalue in A if avalue not in B]

这适用于任何类型的数组元素(只要它们可以比较是否相等),并保留原始顺序。但它需要的最坏情况时间与 成正比len(A) * len(B)

于 2013-10-15T18:42:21.010 回答