我想知道是否有任何方法可以从数字列表中获取长度n
的所有组合。
例如,如果我的列表是[1, 2, 3, 4]
,我想输出(如果我选择n = 3)
[1, 2, 3]
[1, 2, 4]
[1, 3, 4]
[2, 3, 4]
像[2,1,3]这样的其他排列对我没用。
答案 0 :(得分:25)
itertools可以做到这一点
import itertools
for comb in itertools.combinations([1, 2, 3, 4], 3):
print comb
输出
(1, 2, 3)
(1, 2, 4)
(1, 3, 4)
(2, 3, 4)
答案 1 :(得分:1)
如果您不想一次计算所有组合,可以使生成器返回长度为n的组合,如下所示:
def combinations(list_get_comb, length_combination):
""" Generator to get all the combinations of some length of the elements of a list.
:param list_get_comb: (list) List from which it is wanted to get the combination of its elements.
:param length_combination: (int) Length of the combinations of the elements of list_get_comb.
:return:
* :generator: Generator with the combinations of this list.
"""
# Generator to get the combinations of the indices of the list
def get_indices_combinations(sub_list_indices, max_index):
""" Generator that returns the combinations of the indices
:param sub_list_indices: (list) Sub-list from which to generate ALL the possible combinations.
:param max_index: (int) Maximum index.
:return:
"""
if len(sub_list_indices) == 1: # Last index of the list of indices
for index in range(sub_list_indices[0], max_index + 1):
yield [index]
elif all([sub_list_indices[-i - 1] == max_index - i for i in
range(len(sub_list_indices))]): # The current sublist has reached the end
yield sub_list_indices
else:
for comb in get_indices_combinations(sub_list_indices[1:],
max_index): # Get all the possible combinations of the sublist sub_list_indices[1:]
yield [sub_list_indices[0]] + comb
# Advance one position and check all possible combinations
new_sub_list = []
new_sub_list.extend([sub_list_indices[0] + i + 1 for i in range(len(sub_list_indices))])
for new_comb in get_indices_combinations(new_sub_list, max_index):
yield new_comb # Return all the possible combinations of the new list
# Start the algorithm:
sub_list_indices = list(range(length_combination))
for list_indices in get_indices_combinations(sub_list_indices, len(list_get_comb) - 1):
yield [list_get_comb[i] for i in list_indices]
通过致电:
comb = combinations([1, 2, 3, 4], 3)
您可以通过调用next(comb)
或在循环for c in comb:
中使用生成器来逐一计算长度3的可能组合。
此代码的优点是,如果列表很长,有很多可能的组合,并且您想要获得满足某些条件的所有可能组合中的一种,则无需计算所有可能的组合组合,然后根据该标准对其进行过滤。您可以一个一个地生成它们,直到找到符合您条件的组合。这将在计算上更加有效。同样,请注意,上面的代码仅计算长度为n的那些组合,而不是计算所有可能的组合,然后按长度过滤它们,这也使效率更高。
但是,如果需要,您可以通过列出list(comb)
一次计算所有组合。
答案 2 :(得分:0)
添加递归函数:
def combinations(array, tuple_length, prev_array=[]):
if len(prev_array) == tuple_length:
return [prev_array]
combs = []
for i, val in enumerate(array):
prev_array_extended = prev_array.copy()
prev_array_extended.append(val)
combs += combinations(array[i+1:], tuple_length, prev_array_extended)
return combs
combinations([1, 2, 3, 4], 3)
输出:
[[1, 2, 3],
[1, 2, 4],
[1, 3, 4],
[2, 3, 4]]