我想取列表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]
我想取列表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]
当前回答
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上迭代一次。
其他回答
在set中查找值比在list中查找值更快:
[item for item in x if item not in set(y)]
我相信这将会比:
[item for item in x if item not in y]
两者都保持了列表的顺序。
我们也可以使用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]
使用集合差
>>> z = list(set(x) - set(y))
>>> z
[0, 8, 2, 4, 6]
或者你可以让x和y是集合所以你不需要做任何转换。
试试这个。
def subtract_lists(a, b):
""" Subtracts two lists. Throws ValueError if b contains items not in a """
# Terminate if b is empty, otherwise remove b[0] from a and recurse
return a if len(b) == 0 else [a[:i] + subtract_lists(a[i+1:], b[1:])
for i in [a.index(b[0])]][0]
>>> x = [1,2,3,4,5,6,7,8,9,0]
>>> y = [1,3,5,7,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0]
>>> x = [1,2,3,4,5,6,7,8,9,0,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0, 9] #9 is only deleted once
>>>
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上迭代一次。