Python非唯一置换处理

时间:2018-12-13 16:32:53

标签: python python-3.x combinations permutation itertools

我正在尝试使用itertools产品解决问题。这是一个排列问题,但是值不是唯一的,例如:

list = [1,1,2,2,3,3]
#result should be
[1,2,1,2,3,3], [2,2,1,1,3,3], .....

我尝试使用set(itertools.permutations(list)),这是直接的答案,但是对于不同的值和较长的列表,它的处理时间太长了。 我也尝试过x = itertools.product(set(list),repeat=len(list)),然后从不满足原始列表值计数的项中清除x(即,生成的列表必须具有两个1,两个2和两个3s),此解决方案是速度更快,但是此答案会引发大量的MemoryError,因为它尝试将输出存储在内存中,然后对其进行处理。

我也尝试遍历乘积结果(即for i in itertools.product(set(list),repeat=len(list))并选择要存储在哪些迭代中以及丢弃哪些迭代),该解决方案解决了内存错误问题,但几乎和第一个一样慢,其中代码可以运行几个小时。

有人对如何解决这个问题有什么建议吗?

1 个答案:

答案 0 :(得分:0)

这是解决问题的方法。取每个唯一的起始值,然后取值中的所有唯一组合,并删除起始值。这样可以避免生成任何重复项,而只存储每个位置使用的唯一值,因此在最坏的情况下,n个元素列表在内存中是n平方的。

导入itertools

def unique_permutations(values):
    if not values:
        yield []
        return
    seen = set()
    for idx, first in enumerate(values):
        if first in seen:
            continue
        seen.add(first)

        rest = values[:idx] + values[idx+1:]
        for perm in unique_permutations(rest):
            yield [first] + perm

values = [1, 1, 2, 2, 3, 3]
for perm in unique_permutations(values):
    print(perm)

输出:

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