我有一组值,想要创建包含2个元素的所有子集的列表。
例如,源集([1,2,3])
具有以下2元素子集:
set([1,2]), set([1,3]), set([2,3])
有没有办法在python中执行此操作?
答案 0 :(得分:27)
好像你想要itertools.combinations
:
>>> list(itertools.combinations((1, 2, 3), 2))
[(1, 2), (1, 3), (2, 3)]
如果你想要套装,你必须明确地转换它们。如果您不介意迭代而不是列表,并且您使用的是Python 3,则可以使用map
:
>>> s = set((1, 2, 3))
>>> map(set, itertools.combinations(s, 2))
<map object at 0x10cdc26d8>
要一次查看所有结果,您可以将map
的输出传递给list
。 (在Python 2中,map
的输出自动为列表。)
>>> list(map(set, itertools.combinations(s, 2)))
[{1, 2}, {1, 3}, {2, 3}]
但是,如果你知道你需要一个列表,那么列表理解会稍微好一些(h / t Jacob Bowyer):
>>> [set(i) for i in itertools.combinations(s, 2)]
[{1, 2}, {1, 3}, {2, 3}]
答案 1 :(得分:2)
这是包含所有双元素集的{1, 2, 3}
(或任何集合)的power set的子集。
请参阅Python itertools
documentation并搜索术语“powerset”以获取此问题的一般答案。
答案 2 :(得分:1)
为了给出另一个观点,我找到了一种方法来迭代{1.....N}
的所有2的子集,所以我将itertools.combinations
置于测试中:
import itertools
from time import time
N = 7000
lst = [i for i in xrange(N)]
st = time()
c1 = 0
for x in itertools.combinations(lst, 2):
c1 += 1
print "combinations: %f" % (time()-st)
st = time()
c2=0
for x in xrange(N):
for y in xrange(x):
c2 += 1
print "double loop: %f" % (time()-st)
print "c1=%d,c2=%d" % (c1,c2)
# prints:
#combinations: 4.247000
#double loop: 3.479000
# c1=24496500,c2=24496500
所以我猜你不应该总是变成一般的解决方案....如果你事先知道你想要的子集的大小,那么使用for循环迭代应该更有效。
另请注意,您不应迭代list(itertools.combinations(lst, 2))
,因为此移动会创建列表(并且比使用生成器本身要慢得多)。