从另一个列表中删除一个

时间:2012-01-29 12:48:00

标签: python

在python(2.7)中我们可以这样做:

>>> a = [1, 2, 3]
>>> b = [4 , 5]
>>> a + b
[1, 2, 3, 4, 5]

但是我们不能做 - b。

由于python似乎对几乎所有内容都有一些很酷的东西,在你看来,做一个-b的最蟒蛇风格是什么?

字典的类似问题,既不能做+ b,也不能做a-b,其中a和b都是字典。感谢。

8 个答案:

答案 0 :(得分:11)

您可以使用套装执行此操作:

>>> s = set([1,2,3] + [4,5])
>>> s - set([4, 5])
{1, 2, 3}

当然作为集合的主要区别不能包含重复元素。

答案 1 :(得分:5)

我愿意:

>>> a = [1, 2, 3]
>>> b = [2, 3]
>>> filter(lambda x: x not in b, a)
[1]

或使用列表推导

[x for x in a if x not in b]

对字典也可以这样做。

Set已定义了运算符-以及方法differencesymmetric_difference。如果您打算大量使用该操作,请使用set而不是list或dict。

答案 2 :(得分:3)

我会尝试[x for x in a if a not in b]

答案 3 :(得分:2)

答案取决于a - b所需的语义。

如果您只想要第一个元素,那么切片是自然的方法:

In [11]: a = [1, 2, 3]

In [12]: b = [4 , 5]

In [13]: ab = a + b

In [14]: ab[:len(a)]
Out[14]: [1, 2, 3]

另一方面,如果要删除第二个列表中未找到的第一个列表的元素:

In [15]: [v for v in ab if v not in b]
Out[15]: [1, 2, 3]

使用集合更自然地表达第二种类型的操作:

In [18]: set(ab) - set(b)
Out[18]: set([1, 2, 3])

请注意,通常这不会保留元素的顺序(因为集合是无序的)。如果排序很重要且b可能很长,则将b转换为集合可能会提高效果:

In [19]: bset = set(b)

In [20]: [v for v in ab if v not in bset]
Out[20]: [1, 2, 3]

对于字典,已经存在就地“添加”操作。它被称为dict.update()

答案 4 :(得分:1)

y = set(b)
aminusb = filter(lambda p: p not in y,a)

答案 5 :(得分:1)

试试这个:

def list_sub(lst1, lst2):
    s = set(lst2)
    return [x for x in lst1 if x not in s]

list_sub([1, 2, 3, 1, 2, 1, 5], [1, 2])
> [3, 5]

这是一个O(n+m)解决方案,因为它使用预先计算的set,因此会员资格查询速度很快。此外,它将保留原始元素的顺序并删除重复项。

答案 6 :(得分:0)

订单未保留,但它有您想要的结果:

>>> def list_diff(a, b):
...     return list(set(a) - set(b))
... 
>>> print list_diff([1, 2, 3, 1, 2, 1], [1, 2])
[3]

答案 7 :(得分:0)

这是我的首选选项,一个涉及使用for循环另一个转换来设置。如果列表大小为10,则可以接受循环的小列表大小,

In [65]: d1 = range(10)

In [66]: d2 = range(1)

In [67]: %timeit [x for x in d1 if x not in d2]
1000000 loops, best of 3: 827 ns per loop

In [68]: %timeit list(set(d1)-set(d2))
1000000 loops, best of 3: 1.25 µs per loop

但是如果列表大小足够大,那么你应该使用set,

In [69]: d1 = range(10000)

In [70]: d2 = range(1000)

In [71]: %timeit [x for x in d1 if x not in d2]
10 loops, best of 3: 105 ms per loop

In [72]: %timeit list(set(d1)-set(d2))
1000 loops, best of 3: 566 µs per loop