找到多组交集的最佳方法是什么?

use*_*293 232 python set set-intersection

我有一套套装:

setlist = [s1,s2,s3...]
Run Code Online (Sandbox Code Playgroud)

我想要s1∩s2∩s3...

我可以通过执行一系列成对s1.intersection(s2)等来编写一个函数来完成它.

有推荐的,更好的或内置的方式吗?

sth*_*sth 406

从Python 2.6版开始,您可以使用多个参数set.intersection(),例如

u = set.intersection(s1, s2, s3)
Run Code Online (Sandbox Code Playgroud)

如果集合在列表中,则转换为:

u = set.intersection(*setlist)
Run Code Online (Sandbox Code Playgroud)

这里*a_list列表扩展

  • 对于可能和我有同样问题的其他人,我在这里找到答案:http://stackoverflow.com/questions/400739/what-does-asterisk-mean-in-python (8认同)
  • @RadioControlled 没有集合的交集没有在数学上定义,所以这个_应该_失败。请参阅 Patrick Suppes 的“公理集合论”以供参考。 (3认同)
  • 那么当参数可能为零时该怎么办呢?排成一行? (2认同)
  • @RadioControlled 对于在 setlist 为空时工作的单行程序,请使用 `u = set.intersection(*setlist) if setlist else set()` (2认同)

Mik*_*ham 62

从2.6开始,set.intersection任意多次迭代.

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s3 = set([2, 4, 6])
>>> s1 & s2 & s3
set([2])
>>> s1.intersection(s2, s3)
set([2])
>>> sets = [s1, s2, s3]
>>> set.intersection(*sets)
set([2])
Run Code Online (Sandbox Code Playgroud)

  • 不,它不能采用零个迭代。 (3认同)

Tho*_*hle 19

显然set.intersection你想要的就是这里,但是如果你需要概括"把所有这些的总和","拿出所有这些的产品","把所有这些的xor",你正在寻找的是reduce功能:

from operator import and_
from functools import reduce
print(reduce(and_, [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
Run Code Online (Sandbox Code Playgroud)

要么

print(reduce((lambda x,y: x&y), [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
Run Code Online (Sandbox Code Playgroud)


Aym*_*ieh 11

如果你没有Python 2.6或更高版本,另一种方法是编写一个显式的for循环:

def set_list_intersection(set_list):
  if not set_list:
    return set()
  result = set_list[0]
  for s in set_list[1:]:
    result &= s
  return result

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])
Run Code Online (Sandbox Code Playgroud)

您还可以使用reduce:

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])
Run Code Online (Sandbox Code Playgroud)

然而,许多Python程序员不喜欢它,包括Guido本人:

大约12年前,Python获得了lambda,reduce(),filter()和map(),这是(我相信)一个错过了他们并提交了工作补丁的Lisp黑客的礼貌.但是,尽管有PR值,我认为这些功能应该从Python 3000中删除.

所以现在减少().这实际上是我一直非常讨厌的那个,因为除了几个涉及+或*的例子之外,几乎每当我看到一个带有非平凡函数参数的reduce()调用时,我都需要抓笔和纸来在我理解reduce()应该做什么之前,图表实际上被输入到该函数中的是什么.所以在我看来,reduce()的适用性几乎仅限于关联运算符,在所有其他情况下,最好明确地写出累积循环.

  • 请注意,Guido说使用`reduce`是"仅限于关联运算符",这适用于这种情况.`reduce`通常很难弄明白,但是```并不是那么糟糕. (8认同)

Sta*_*kos 6

我相信最简单的事情是:

#assuming three sets
set1 = {1,2,3,4,5}
set2 = {2,3,8,9}
set3 = {2,10,11,12}

#intersection
set4 = set1 & set2 & set3
Run Code Online (Sandbox Code Playgroud)

set4 将是 set1 、 set2 、 set3 的交集,并且包含值 2。

print(set4)

set([2])
Run Code Online (Sandbox Code Playgroud)