Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 找到多个集合交集的最佳方法?_Python_Set_Set Intersection - Fatal编程技术网

Python 找到多个集合交集的最佳方法?

Python 找到多个集合交集的最佳方法?,python,set,set-intersection,Python,Set,Set Intersection,我有一个集合列表: setlist = [s1,s2,s3...] 我要s1∩ s2∩ s3 我可以编写一个函数,通过执行一系列成对的s1.交集(s2)等来实现 有推荐的、更好的或内置的方法吗?如果您没有Python 2.6或更高版本,另一种方法是编写一个显式for循环: def set_list_intersection(set_list): if not set_list: return set() result = set_list[0] for s in set_l

我有一个集合列表:

setlist = [s1,s2,s3...]
我要s1∩ s2∩ s3

我可以编写一个函数,通过执行一系列成对的
s1.交集(s2)
等来实现


有推荐的、更好的或内置的方法吗?

如果您没有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])
您还可以使用
reduce

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])
但是,许多Python程序员不喜欢它:

大约12年前,Python获得了lambda、reduce()、filter()和map(),这是(我相信)一位Lisp黑客的功劳,他错过了它们并提交了工作补丁。但是,尽管有PR值,我认为这些特性应该从python3000中删除

所以现在reduce()。这实际上是我最讨厌的一个,因为除了一些涉及+或*的示例外,几乎每次我看到带有非平凡函数参数的reduce()调用时,我都需要抓起纸笔来绘制实际输入到该函数中的内容,然后才能理解reduce()应该做什么。所以在我看来,reduce()的适用性非常局限于关联运算符,在所有其他情况下,最好显式写出累加循环


从Python 2.6版开始,您可以使用多个参数

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

u = set.intersection(*setlist)
其中
*是一个_列表


请注意,
set.intersection
不是静态方法,但它使用函数表示法应用第一个集合与列表其余部分的交集。因此,如果参数列表为空,则此操作将失败。

从2.6开始,
设置。交集
可以使用任意多个iterables

>>> 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])

在这里,我提供了一个多集交叉的通用函数,试图利用可用的最佳方法:

def multiple_set_intersection(*sets):
    """Return multiple set intersection."""
    try:
        return set.intersection(*sets)
    except TypeError: # this is Python < 2.6 or no arguments
        pass

    try: a_set= sets[0]
    except IndexError: # no arguments
        return set() # return empty set

    return reduce(a_set.intersection, sets[1:])
def多个集合相交(*集合):
“”“返回多集交集。”“”
尝试:
返回集合。交点(*集合)
除了TypeError:#这是Python<2.6或没有参数
通过
try:a_set=set[0]
除索引器外:#无参数
返回集()#返回空集
返回reduce(a_set.intersection,set[1:])

Guido可能不喜欢
reduce
,但我有点喜欢它:)

显然
set。这里需要的是交集
,但如果您需要“取所有这些的总和”、“取所有这些的乘积”、“取所有这些的xor”,您需要的是
reduce
函数:

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


Jean-François Fabre集合。intesection(*集合列表)的答案无疑是最Pyhtonic的,并且是公认的答案

对于那些希望使用reduce的用户,以下操作也将起作用:


减少(set.intersection,列出集合)

我认为最简单的方法是:

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

#intersection
set4 = set1 & set2 & set3
set4将是set1、set2、set3的交点,并包含值2

print(set4)

set([2])

注意,Guido说使用
reduce
仅限于关联运算符,这在本例中适用
reduce
通常很难理解,但对于
&
来说,这并不坏。请查看有关reduce的有用优化。通常,它可以很好地用于构建列表、集合、字符串等。值得一看的是,当
结果
为空时,您可以通过中断循环进行优化。您应该检查
集合
的长度,而不是试图访问
集合[0]
并捕获
索引器。这不是简单的检查<代码>在最终返回时使用了一套
。如果设置了其他设置()
,您不能
返回reduce(设置[0],设置[1:])吗?是的,谢谢。代码应该更改,因为如果可以的话,应该避免依赖
try
/
除外。这是一种代码气味,效率低下,并且可以隐藏其他问题。不,它不能接受零个可重用项。那么,当可能存在零个参数时,该怎么办?在一行中?@RADIOCONTROLED对于在setlist为空时工作的一行,如果setlist else set()
对sol的复杂性有任何评论,请使用
u=set.intersection(*setlist)。如上所述?@CKM,确切地说,我们需要事先按大小在
setlist
中对集合进行排序,还是该函数为我们这样做?这与“应用列表中第一个集合与其余集合的交集”的语句相矛盾。@RadioControlled没有集合的交集是没有数学定义的,因此这应该失败。请参阅Patrick Suppes的“公理集理论”。在这里,我非常肯定列表的顺序对速度很重要。通过增加列表中相邻集合的大小或减少预期交集大小来排序,以更精确。
#assuming three sets
set1 = {1,2,3,4,5}
set2 = {2,3,8,9}
set3 = {2,10,11,12}

#intersection
set4 = set1 & set2 & set3
print(set4)

set([2])