使用重复元素python生成列表的r长度排列

时间:2014-06-11 10:51:42

标签: python permutation itertools

我的问题类似于提问here的问题。与此问题不同,我需要一种算法,该算法生成具有重复元素的给定列表的r元组排列。

举个例子:

list1 = [1,1,1,2,2]

for i in permu(list1, 3):
     print i 

[1,1,1]
[1,1,2]
[1,2,1]
[2,1,1]
[1,2,2]
[2,1,2]
[2,2,1]

似乎itertools.permutations在这里可以正常工作,添加一个简单的过滤来删除重复的过滤。然而,在我的实际情况中,列表比这个例子长得多,因为你已经知道itertools.permutations的复杂性随着列表长度的增加而呈指数增长。

到目前为止,我的内容如下。此代码执行所描述的作业,但效率不高。

def generate_paths(paths, N = None):
    groupdxs = [i for i, group in enumerate(paths) for _ in range(len(group))]
    oldCombo = []
    result = []
    for dxCombo in itertools.permutations(groupdxs, N):
        if dxCombo <= oldCombo: # as simple filter
            continue
        oldCombo = dxCombo
        parNumbers = partialCombinations(dxCombo, len(paths))
        if not parNumbers.count(0) >= len(paths)-1: # all of nodes are coming from same path, same graph 
            groupTemps = []
            for groupInd in range(len(parNumbers)):
                groupTemp = [x for x in itertools.combinations(paths[groupInd], parNumbers[groupInd])]
                groupTemps.append(groupTemp)
            for parGroups in itertools.product(*groupTemps):
                iters = [iter(group) for group in parGroups]
                p =  [next(iters[i]) for i in dxCombo]
                result.append(p)
    return result


def partialCombinations(combo, numGruops):
    tempCombo = list(combo)
    result = list([0] * numGruops)
    for x in tempCombo:
        result[x] += 1
    return result

在第一个for循环中,我需要生成所有可能的r长度元组,这会使算法变慢。在上面的链接中没有使用r长度的排列有一个很好的解决方案。我怎样才能采用这种算法来挖掘?还是有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

对于你的情况,我还没有想到这一点,但这是另一种方法。

您可以提供一个没有重复项的小列表,而不是为列表提供大型列表。您可以使用combination_with_replacement生成这些较小的列表(您需要过滤它们以匹配原始输入中的重复数量),然后获取每个组合的排列。

possible_values = (1,2)
n_positions = 3

sorted_combinations = itertools.combinations_with_replacement(possible_values, n_positions)
unique_permutations = set()
for combo in sorted_combinations:
    # TODO: Do filtering for acceptable combinations before passing to permutations.
    for p in itertools.permutations(combo):
        unique_permutations.add(p)


print "len(unique_permutations) = %i. It should be %i^%i = %i.\nPermutations:" % (len(unique_permutations), len(possible_values), n_positions, pow(len(possible_values), n_positions))
for p in unique_permutations:
    print p