如何以pythonic方式使用pop用于多维数组

时间:2013-10-15 18:27:53

标签: python list

我想从列表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 个答案:

答案 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)成正比。