给出这样一个列表:
num = [1, 2, 3, 4, 5]
有10种三元素组合:
[123, 124, 125, 134, 135, 145, 234, 235, 245, 345]
如何生成此列表?
答案 0 :(得分:10)
import itertools
num = [1, 2, 3, 4, 5]
combinations = []
for combination in itertools.combinations(num, 3):
combinations.append(int("".join(str(i) for i in combination)))
# => [123, 124, 125, 134, 135, 145, 234, 235, 245, 345]
print len(combinations)
# => 10
修改强>
如果您只对组合数感兴趣,可以跳过int(),join()和str()。 itertools.combinations()为您提供可能足够好的元组。
答案 1 :(得分:5)
您在谈论combinations。有 n!/(k!*(n - k)!)从 n 元素列表中获取 k 元素的方法。所以:
>>> num = [1, 2, 3, 4, 5]
>>> fac = lambda n: 1 if n < 2 else n * fac(n - 1)
>>> combos = lambda n, k: fac(n) / fac(k) / fac(n - k)
>>> combos(len(num), 3)
10
仅在您确实要生成所有组合时才使用itertools.combinations。 不如果您只想知道不同组合的数字。
此外,与使用上面显示的代码相比,有更有效的方法来计算组合数。例如,
>>> from operator import truediv, mul
>>> from itertools import starmap
>>> from functools import reduce
>>> combos = lambda n, k: reduce(mul, starmap(truediv, zip(range(n, n - k, -1), range(k, 0, -1))))
>>> combos(len(num), 3)
10.0
(注意,此代码使用浮点除法!)
答案 2 :(得分:2)
我相信您正在寻找binomial coefficient:
答案 3 :(得分:2)
从输入迭代中返回元素的r长度子序列。
组合以字典排序顺序发出。因此,如果输入iterable已排序,则组合元组将按排序顺序生成。
元素根据其位置而不是其价值被视为唯一。因此,如果输入元素是唯一的,则每个组合中都不会有重复值。
>>> num = [1, 2, 3, 4, 5]
>>> [i for i in itertools.combinations(num,3)]
[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5),
(2, 4, 5), (3, 4, 5)]
>>>