列表和集合之间的差异运算符

Jiv*_*van 1 python python-3.x

是否有一个运算符可以List根据 a 的内容从 a中删除元素Set

我想做的事情已经可以通过这样做:

words = ["hello", "you", "how", "are", "you", "today", "hello"]
my_set = {"you", "are"}

new_list = [w for w in words if w not in my_set]
# ["hello", "how", "today", "hello"]
Run Code Online (Sandbox Code Playgroud)

这种列表理解让我困扰的是,对于巨大的集合,它看起来不如可-在两个集合之间使用的运算符有效。因为在列表推导式中,迭代发生在 Python 中,而使用运算符时,迭代发生在C和 中,并且级别更低,因此速度更快。

那么,是否有某种方法可以比使用列表理解更短/更干净/更有效地计算列表和集合之间的差异,例如:

# I know this is not possible, but does something approaching exist?
new_list = words - my_set
Run Code Online (Sandbox Code Playgroud)

长话短说

我正在寻找一种方法来Set从 a中删除 a 中存在的所有元素List,即:

  • 清洁器(也许是内置的)
  • 和/或更高效

比我所知道的可以通过列表理解来完成。

pok*_*oke 5

不幸的是,对此的唯一答案是:不,对于这种操作,没有以本机代码实现的内置方法。

\n\n
\n

这个列表理解让我困扰的是,对于庞大的集合,它对我来说看起来不如-在两个集合之间使用的运算符有效。

\n
\n\n

我认为 \xe2\x80\x99 这里重要的是 \xe2\x80\x9clooks\xe2\x80\x9d 部分。是的,列表推导式在 Python 中运行得比设置差异更多,但我假设您的大多数应用程序实际上在 Python 中运行(否则您可能应该使用 C 进行编程)。所以你应该考虑它是否真的很重要。在 Python 中迭代列表很快,并且集合上的成员资格测试也非常快(恒定时间,并在本机代码中实现)。如果你看一下列表推导式,你会发现它们也非常快。所以它可能不会\xe2\x80\x99那么重要。

\n\n
\n

因为在列表推导式中,迭代发生在 Python 中,而使用运算符时,迭代发生在 C 中,并且级别更低,因此速度更快。

\n
\n\n

确实,本机操作速度更快,但它们也更专业、更有限,并且灵活性较低。对于集合来说,差异是很容易的。集合是一个数学概念,定义非常明确。

\n\n

但是当谈论 \xe2\x80\x9clist 差异\xe2\x80\x9d 或 \xe2\x80\x9clist 并设置差异\xe2\x80\x9d (或更广义的 \xe2\x80\x9clist 和可迭代差异\xe2 \x80\x9d?)它变得更加不清楚。有很多悬而未决的问题:

\n\n
    \n
  • 如何处理重复项?X如果原始列表中有两个,而X减数中只有一个,是否都应该X从列表中消失?应该只有一个消失吗?如果有,是哪一个,为什么?

  • \n
  • 订单如何处理?订单是否应该保留原始列表中的顺序?减数中元素的顺序有什么影响吗?

  • \n
  • 如果我们想根据除相等以外的其他条件来减去成员怎么办?对于集合,很明显它们始终致力于成员的相等性(和哈希值)。列表 don\xe2\x80\x99t,因此列表在设计上更加灵活。通过列表推导,我们可以轻松地使用任何类型的条件从列表中删除元素;有了 \xe2\x80\x9clist 差异\xe2\x80\x9d,我们将被限制为相等,如果你仔细想想,这实际上可能是一种罕见的情况。

    \n\n

    如果您需要计算差异(甚至某些有序集合) ,则它\xe2\x80\x99s可能更有可能使用集合。对于过滤列表,在极少数情况下您可能希望最终得到过滤后的列表,因此使用生成器表达式(或 Python 3 函数)并稍后使用它可能更常见,而filter()无需创建内存中的过滤列表。

  • \n
\n\n

我\xe2\x80\x99m 想说的是列表差异的用例并不像集合差异那么清晰。如果有一个用例,那也可能是一个非常罕见的用例。一般来说,我认为\xe2\x80\x99不值得为此增加Python实现的复杂性。特别是当 Python 中的替代方案(例如列表理解)已经和现在一样快时。

\n