生成列表中每3个项目的2个项目组合

时间:2013-04-16 13:25:34

标签: python list combinations

我希望按3项列出一个列表,并尽可能简洁地通过2项组合迭代每个这样的组。我尝试了一些甚至没有编译的东西:

from itertools import combinations
L = [1,2,3,4,5,6]
for a,b in combinations(zip(*[iter(L)]*3), 2): 
    print "{0:d} {1:d}".format(a,b)

预期输出

1,2
1,3
2,3
4,5
4,6
5,6

我可以通过命令性陈述来做到这一点,但我正在寻找一种声明性的方式。

3 个答案:

答案 0 :(得分:2)

你很亲密。您需要一次进行组合1分组,然后chain结果(实际上,此处chain.from_iterable更合适)。

from itertools import combinations,chain

lst = [1,2,3,4,5,6]
def group(a,n):
    return zip(*[iter(a)]*n)

for a,b in chain.from_iterable(combinations(grp, 2) for grp in group(lst,3)): 
    print "{0} {1}".format(a,b)

答案 1 :(得分:2)

您已接近,但您需要将combinations()函数应用于zip()石斑鱼序列输出中的每个元组:

from itertools import combinations, chain

for a, b in chain.from_iterable(combinations(group, 2) for group in zip(*[iter(a)]*3)):
    print "{} {}".format(a,b)

由于您现在有combinations()个结果的序列,我使用chain.from_iterable()将每个结果的输出合并为最终序列。

这会产生所需的输出:

>>> for a, b in chain.from_iterable(combinations(group, 2) for group in zip(*[iter(a)]*3)):
...     print "{} {}".format(a,b)
... 
1 2
1 3
2 3
4 5
4 6
5 6

答案 2 :(得分:1)

以下是基于itertoolsoperator的解决方案。不像其他解决方案那样简洁,但FWIW:

from itertools import imap, combinations, repeat, count, takewhile, izip, chain
from operator import getitem, truth
L = [1,2,3,4,5,6]
slicers = izip(count(0, 3), count(3, 3))
slices = (getitem(L, slice(*x)) for x in slicers)
slices = takewhile(truth, slices)
for x in chain.from_iterable(imap(combinations, slices, repeat(2))):
    print x

...
(1, 2)
(1, 3)
(2, 3)
(4, 5)
(4, 6)
(5, 6)