Python-具有唯一值的排列

发布于 2021-02-02 23:20:49

itertools.permutations会根据其位置而不是其值来生成其元素被视为唯一的元素。所以基本上我想避免重复这样的事情:

>>> list(itertools.permutations([1, 1, 1]))
[(1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1), (1, 1, 1)]

之后的过滤是不可能的,因为在我的情况下,排列的数量太大。

有人知道合适的算法吗?

非常感谢你!

编辑:

我基本上想要的是以下内容:

x = itertools.product((0, 1, 'x'), repeat=X)
x = sorted(x, key=functools.partial(count_elements, elem='x'))

这是不可能的,因为sorted创建列表并且itertools.product的输出太大。

抱歉,我应该已经描述了实际问题。

关注者
0
被浏览
185
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。
    class unique_element:
        def __init__(self,value,occurrences):
            self.value = value
            self.occurrences = occurrences
    
    def perm_unique(elements):
        eset=set(elements)
        listunique = [unique_element(i,elements.count(i)) for i in eset]
        u=len(elements)
        return perm_unique_helper(listunique,[0]*u,u-1)
    
    def perm_unique_helper(listunique,result_list,d):
        if d < 0:
            yield tuple(result_list)
        else:
            for i in listunique:
                if i.occurrences > 0:
                    result_list[d]=i.value
                    i.occurrences-=1
                    for g in  perm_unique_helper(listunique,result_list,d-1):
                        yield g
                    i.occurrences+=1
    
    
    
    
    a = list(perm_unique([1,1,2]))
    print(a)
    

    结果:

    [(2, 1, 1), (1, 2, 1), (1, 1, 2)]
    

    编辑(这是如何工作的):

    我将上面的程序改写得更长,但可读性更好。

    我通常很难解释一些事情,但是让我尝试一下。为了理解它是如何工作的,你必须了解一个类似但更简单的程序,该程序将产生所有带有重复的排列。

    def permutations_with_replacement(elements,n):
        return permutations_helper(elements,[0]*n,n-1)#this is generator
    
    def permutations_helper(elements,result_list,d):
        if d<0:
            yield tuple(result_list)
        else:
            for i in elements:
                result_list[d]=i
                all_permutations = permutations_helper(elements,result_list,d-1)#this is generator
                for g in all_permutations:
                    yield g
    

    这个程序显然要简单得多:d代表permutations_helper中的depth并具有两个功能。一个函数是递归算法的停止条件,另一个函数用于传递的结果列表。

    我们不返回每个结果,而是产生它。如果没有功能/运算符,yield我们将不得不在停止条件时将结果推送到某个队列中。但是这样一来,一旦满足停止条件,结果就会通过所有堆栈传播到调用者。这样做的目的是
    for g in perm_unique_helper(listunique,result_list,d-1): yield g使每个结果都传播给调用方。

    回到原始程序:我们有一个唯一元素列表。在使用每个元素之前,我们必须检查仍有多少个元素可以推送到result_list上。使用此程序非常类似于permutations_with_replacement。不同之处在于,每个元素的重复次数不能超过perm_unique_helper中的重复次数。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看