我想从列表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方式来做它。请建议。
答案 0 :(得分:5)
首先将B
转换为set
,然后使用列表推导从A
创建一个新数组:
s = set(B)
A = [item for item in A if item not in s]
集合中的项目查找是O(1)
操作。
如果您不想更改id()
的{{1}},请:
A
答案 1 :(得分:2)
列出对救援的理解:
[item for item in A if item not in B]
然而,这会创建一个新列表。您可以从函数返回列表。
或者,如果您可以删除列表A
中的任何重复项,或者没有重复项,则可以使用set
区别:
return list(set(A) - set(B))
有一点需要注意,这不会保留A
中元素的顺序。所以,如果你想按顺序排列元素,这不是你想要的。请改用第一种方法。
答案 2 :(得分:2)
列表理解怎么样?
def remove(removeList, fromList):
return [x for x in fromList if x not in removeList]
此外,为了让生活更轻松,删除更快,您可以从列表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
函数,虽然有人会说它是非pythonic的,你应该使用列表生成器。无论哪种方式,这是一个例子:
def remove(removeList, fromList):
removeSet = set(removeList)
return filter(lambda x : x not in removeSet, fromList)
答案 3 :(得分: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)
成正比。