我正在尝试为排列目的创建一个生成器。我知道在python中有其他方法可以做到这一点。但这是为了其他的东西。但是我无法屈服于这些价值。你可以帮忙吗?
def perm(s,p=0,ii=0):
l=len(s)
s=list(s)
if(l==1):
print ''.join(s)
elif((l-p)==2):
yield ''.join(s)
yield ''.join([''.join(s[:-2]),s[-1],s[-2]])
#print ''.join(s)
#print ''.join([''.join(s[:-2]),s[-1],s[-2]])
else:
for i in range(p,l):
tmp=s[p]
s[p]=s[i]
s[i]=tmp
perm(s,p+1,ii)
答案 0 :(得分:5)
你的专栏perm(s,p+1,ii)
没有做任何事,真的:就像输入一样
>>> perm("fred")
<generator object perm at 0xb72b9cd4>
但是,如果你从那个电话中得出,即
for subperm in perm(s, p+1, ii):
yield subperm
然后你会得到
>>> list(perm("abc"))
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
>>> list(perm("abcd"))
['abcd', 'abdc', 'acbd', 'acdb', 'adbc', 'adcb', 'bacd', 'badc', 'bcad', 'bcda', 'bdac', 'bdca', 'cabd', 'cadb', 'cbad', 'cbda', 'cdab', 'cdba', 'dabc', 'dacb', 'dbac', 'dbca', 'dcab', 'dcba']
>>> len(_)
24
>>> len(set(perm("abcd")))
24
看起来没问题。我还没有测试过代码。
顺便说一句,您可以将s[i]
和s[p]
与s[i], s[p] = s[p], s[i]
交换;不需要tmp
变量。
PS:现在你不处理单字符的情况。
答案 1 :(得分:0)
在生成器中,只要您想要返回值yield
。这就像你有一个递归因子函数,如下所示:
>>> def fact(n, result=1):
if n==0: return result
fact(n-1, result*n)
然后你想知道它为什么不返回任何东西:
>>> fact(5)
>>>
原因是函数是递归调用的,但值会丢失。你想做的事:
>>> def fact(n, result=1):
if n==0: return result
return fact(n-1, result*n)
>>> fact(5)
120
类似地,在算法的递归部分中,您可以:
for i in range(p,l):
tmp=s[p]
s[p]=s[i]
s[i]=tmp
perm(s,p+1,ii)
这不会yield
任何东西,因此perm(s,p+1,ii)
调用中的任何值都不会被返回(编辑:实际上,甚至都不会计算它们)。您需要遍历递归调用的结果并依次返回每个结果:
for i in range(p,l):
tmp=s[p]
s[p]=s[i]
s[i]=tmp
for result in perm(s,p+1,ii):
yield result