interesting exercise

Michael Tobis mtobis at gmail.com
Wed May 9 18:38:54 EDT 2007


On May 9, 2:41 pm, castiro... at gmail.com wrote:
> On May 9, 1:13 am, Charles Sanders <C.delete_this.Sand... at BoM.GOv.AU>
> wrote:

> > or even this monstrosity ...
>
> > def permute2( s, n ):
> >    return [ ''.join([ s[int(i/len(s)**j)%len(s)]
> >      for j in range(n-1,-1,-1)])
> >        for i in range(len(s)**n) ]
>
> > print "permute2('abc',2) =", permute2('abc',2)
> > print "len(permute2('13579',3)) =", len(permute2('13579',3))
>
> > permute2('abc',2) = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc',
> >   'ca', 'cb', 'cc']
> > len(permute2('13579',3)) = 125
>
> > Charles
>
> Could you explain, this one, actually?  Don't forget StopIteration.

Heh, it's cute.

Not sure what the issue is with StopIteration. He is modeling the
problem as casting an integer to base N. It's terse, but it does way
too much arithmetic and isn't very readable.

The following uses the same idea more readably and (I expect,
untested) more efficiently, if less tersely. It actually is not too
bad for real code, though I much prefer your recursive list
comprehension and will use that.

def getdigits(number,base,length,alphabet):
    residual = number
    result = ""
    for column in range(length):
	residual,digit = divmod(residual,base)
	result = alphabet[digit] + result
    return result

def permu(alphabet,wordlength):
    total = len(alphabet)**wordlength
    return [getdigits(index,len(alphabet),wordlength,alphabet)
                 for index in range(total)]

if __name__ == "__main__":
    print permu("abc",2)
    print len(permu("13579",3))

mt




More information about the Python-list mailing list