Python-具有唯一值的排列
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的输出太大。
抱歉,我应该已经描述了实际问题。
回答:
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中的重复次数。
以上是 Python-具有唯一值的排列 的全部内容, 来源链接: utcz.com/qa/412789.html