我想取列表x和y的差值:

>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [1, 3, 5, 7, 9]  
>>> x - y
# should return [0, 2, 4, 6, 8]

当前回答

如果列表允许重复元素,你可以使用Counter from collections:

from collections import Counter
result = list((Counter(x)-Counter(y)).elements())

如果你需要保留x中元素的顺序:

result = [ v for c in [Counter(y)] for v in x if not c[v] or c.subtract([v]) ]

其他回答

我们也可以使用set方法来查找两个列表之间的差异

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
y = [1, 3, 5, 7, 9]
list(set(x).difference(y))
[0, 2, 4, 6, 8]

Let:

>>> xs = [1, 2, 3, 4, 3, 2, 1]
>>> ys = [1, 3, 3]  

每一项只保留一次xs - ys == {2,4}

取集合差值:

>>> set(xs) - set(ys)
{2, 4}

删除所有xs - ys == [2,4,2]

>>> [x for x in xs if x not in ys]
[2, 4, 2]

如果ys很大,为了获得更好的性能,只将1个ys转换为一个set:

>>> ys_set = set(ys)
>>> [x for x in xs if x not in ys_set]
[2, 4, 2]

只删除相同数量的出现xs - ys == [2,4,2,1]

from collections import Counter, defaultdict

def diff(xs, ys):
    counter = Counter(ys)
    for x in xs:
        if counter[x] > 0:
            counter[x] -= 1
            continue
        yield x

>>> list(diff(xs, ys))
[2, 4, 2, 1]

1 .将xs转换为set并获取set的差异是不必要的(并且更慢,并且破坏顺序),因为我们只需要在xs上迭代一次。

使用集合差

>>> z = list(set(x) - set(y))
>>> z
[0, 8, 2, 4, 6]

或者你可以让x和y是集合所以你不需要做任何转换。

如果重复和订购项目是问题:

[i为a中的i,如果不是b中的i或b中的i,删除(i)]

a = [1,2,3,3,3,3,4]
b = [1,3]
result: [2, 3, 3, 3, 4]

在set中查找值比在list中查找值更快:

[item for item in x if item not in set(y)]

我相信这将会比:

[item for item in x if item not in y]

两者都保持了列表的顺序。