如何在python中获取长度为n的所有组合

时间:2015-01-15 22:24:00

标签: python combinations

我想知道是否有任何方法可以从数字列表中获取长度n的所有组合。

例如,如果我的列表是[1, 2, 3, 4],我想输出(如果我选择n = 3)

[1, 2, 3]
[1, 2, 4]
[1, 3, 4]
[2, 3, 4]
像[2,1,3]这样的其他排列对我没用。

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]]