递归生成在Python中选择n个k组合的列表 - 但返回一个列表

时间:2016-03-13 19:20:16

标签: python algorithm list recursion combinations

我试图通过遵循包括或不包括每个递归调用的元素的策略来递归地生成所有n个列表的组合(不检查唯一性)。我绝对可以打印出这些组合,但是对于我的生活,我无法弄清楚如何在Python中返回正确的列表。以下是一些尝试:

class getCombinationsClass:

    def __init__(self,array,k):

        #initialize empty array
        self.new_array = []
        for i in xrange(k):
            self.new_array.append(0)

        self.final = []

        self.combinationUtil(array,0,self.new_array,0,k)

    def combinationUtil(self,array,array_index,current_combo, current_combo_index,k):

        if current_combo_index == k:
            self.final.append(current_combo)
            return

        if array_index >= len(array):
            return

        current_combo[current_combo_index] = array[array_index]

        #if current item included
        self.combinationUtil(array,array_index+1,current_combo,current_combo_index+1,k)

        #if current item not included
        self.combinationUtil(array,array_index+1,current_combo,current_combo_index,k)

在上面的示例中,我尝试将结果附加到外部列表中,该列表似乎无法正常工作。我还尝试通过递归构造最终返回的列表来实现它:

def getCombinations(array,k):

    #initialize empty array
    new_array = []
    for i in xrange(k):
        new_array.append(0)

    return getCombinationsUtil(array,0,new_array,0,k)

def getCombinationsUtil(array,array_index,current_combo, current_combo_index,k):

    if current_combo_index == k:
        return [current_combo]

    if array_index >= len(array):
        return []

    current_combo[current_combo_index] = array[array_index]

    #if current item included & not included
    return getCombinationsUtil(array,array_index+1,current_combo,current_combo_index+1,k) + getCombinationsUtil(array,array_index+1,current_combo,current_combo_index,k)

当我对列表[1,2,3]和k = 2进行测试时,对于这两种实现,我一直收到结果[[3,3],[3,3],[3,3] ]。但是,如果我实际打印出' current_combo'内部(current_combo_index == k)if语句中的变量,打印出正确的组合。是什么赋予了?我误解了与变量范围或Python列表有关的事情?

2 个答案:

答案 0 :(得分:3)

第二种方法出错了,因为行

return [current_combo]

返回对current_combo的引用。在程序结束时,返回的所有组合都是对同一current_combo的引用。

您可以通过将行更改为:

来复制current_combo来解决此问题
return [current_combo[:]]

第一种方法失败的原因相同,您需要更改:

self.final.append(current_combo)

self.final.append(current_combo[:])

答案 1 :(得分:2)

检查出来:itertools.combinations。您也可以查看实现。