在我的脑海中出现的唯一更具 声明性 (因此也是 Python 风格)的方法, 可以提高 大型
b(和
a)的 性能
,是使用某种递减计数器:
from collections import Counterclass DecrementCounter(Counter): def decrement(self,x): if self[x]: self[x] -= 1 return True return False
现在我们可以使用列表推导:
b_count = DecrementCounter(b)complement = [x for x in a if not b_count.decrement(x)]
因此,在这里我们跟踪计数
b,因为
a我们查看其中的每个元素是否属于
b_count。如果确实如此,我们将递减计数器并忽略该元素。否则,我们将其添加到中
complement。请注意,这仅适用,如果我们相信
这样的
complement存在。
之后 您已经构建的
complement,您可以检查是否补与存在:
not bool(+b_count)
如果为
False,则 无法构造此类补码 (例如
a=[1]和
b=[1,3])。因此,完整的实现可能是:
b_count = DecrementCounter(b)complement = [x for x in a if not b_count.decrement(x)]if +b_count: raise ValueError('complement cannot be constructed')如果字典查找在 O(1)中 运行 ( 通常是这样,只有在极少数情况下才是 O(n) ),则此算法在 O(| a | + | b |)中运行
(因此,列表)。而该
remove方法通常在 O(| a | x | b |)中运行 。



