permutations - fast & with low memory consumption?
Anton Vredegoor
anton.vredegoor at gmail.com
Tue Dec 19 10:28:11 EST 2006
Gerard Flanagan wrote:
> No claims with respect to speed, but the kslice function here:
>
> http://gflanagan.net/site/python/utils/sequtils/
>
> will give the 'k-subsets' which then need to be permuted -
> alternatively Google.
Maybe the function below could then do these permutations.
Anton.
def _sorted(seq):
""" Return a sorted copy of seq,
preserving the type.
"""
res = seq[0:0]
decorated = ((x,i) for i,x in enumerate(seq))
for x,i in sorted(decorated):
res += seq[i:i+1]
return res
def _swap_and_reverse_tail(R,i,j):
""" Swap R[i] and R[j], reverse R[i+1:].
Returns a copy, preserving the type.
"""
a,b,c,d,e = R[:i],R[i:i+1],R[i+1:j],R[j:j+1],R[j+1:]
return a+d+(c+b+e)[::-1]
def permutations(seq):
""" Generate sorted permutations of any sequence
that can be indexed and sliced, preserving the type.
e.g. seq can be a string, list, tuple or array.
"""
n = len(seq)
if n == 1:
yield seq[:]
elif n >= 2:
R = _sorted(seq)
while True:
yield R
i,j = n-2,n-1
while R[i] >= R[i+1] :
i -= 1
if i == -1:
return
while R[i] >= R[j]:
j -= 1
R = _swap_and_reverse_tail(R,i,j)
def test():
seq = 'gkDr217sKGMNLPsrtqeiczxyqqqqq'
P = permutations(seq)
for i,x in enumerate(P):
print '%s' %(x)
if i == 10:
break
if __name__ == '__main__':
test()
More information about the Python-list
mailing list