我有一个集合列表:
setlist = [s1,s2,s3...]
我想要s1∩s2∩s3…
我可以编写一个函数,通过执行一系列成对的s1.intersection(s2)等来完成它。
s1.intersection(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:
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黑客,他错过了这些,并提交了工作补丁。但是,尽管有公关价值,我认为这些特性应该从Python 3000中删除。 现在reduce()。这实际上是我最讨厌的方法,因为,除了一些涉及+或*的例子外,几乎每次我看到带有非平凡函数参数的reduce()调用时,在我理解reduce()应该做什么之前,我都需要拿起笔和纸来绘制实际输入到该函数中的内容。因此,在我看来,reduce()的适用性在很大程度上仅限于关联运算符,在所有其他情况下,最好显式地写出累加循环。
大约12年前,Python获得了lambda, reduce(), filter()和map(),感谢(我相信)一个Lisp黑客,他错过了这些,并提交了工作补丁。但是,尽管有公关价值,我认为这些特性应该从Python 3000中删除。
现在reduce()。这实际上是我最讨厌的方法,因为,除了一些涉及+或*的例子外,几乎每次我看到带有非平凡函数参数的reduce()调用时,在我理解reduce()应该做什么之前,我都需要拿起笔和纸来绘制实际输入到该函数中的内容。因此,在我看来,reduce()的适用性在很大程度上仅限于关联运算符,在所有其他情况下,最好显式地写出累加循环。
从Python 2.6版起,你可以使用多个参数来set.intersection(),比如
set.intersection()
u = set.intersection(s1, s2, s3)
如果集合在列表中,则转换为:
u = set.intersection(*setlist)
其中*a_list是列表扩张
*a_list
注意,set.intersection是不一个静态方法,但它使用函数符号来应用第一个集合与列表其余部分的交集。如果参数列表为空,就会失败。
set.intersection
从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])
这里我提供了一个多集交集的通用函数,试图利用可用的最佳方法:
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:])
Guido可能不喜欢reduce,但我有点喜欢它:)
显然set.intersection是你在这里想要的,但如果你需要“取所有这些的和”,“取所有这些的乘积”,“取所有这些的异或”的泛化,你要找的是reduce函数:
from operator import and_ from functools import reduce print(reduce(and_, [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
或
print(reduce((lambda x,y: x&y), [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
Jean-François Fabre set. intection (*list_of_sets)的答案绝对是最python的,也是正确的被接受的答案。
对于那些想要使用reduce的人,以下也可以:
reduce(set.intersection, list_of_sets)
我认为最简单的做法是:
#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])