[Tutor] seed & random !?

Kirby Urner urnerk@qwest.net
Mon, 15 Oct 2001 14:32:22 -0700


At 07:36 PM 10/15/2001 +0800, Andrew Wilkins wrote:
> > Indeed.  Below is a function that takes a list of characters
> > and returns all unique permutations thereof:
>
>That's a funky function, Kirby!
>I'm wondering if there's a better way to extend this function,
>so that it returns permutations of specific numbers of elements,
>than what I have (by modifying your code).
>
>Andrew

In practice, permuting 10 or more items is impractical.
So if you're willing to live with a 10 object limit,
you could get away with mapping whatever 10 objects to
single characters '0'..'9' using a dictionary, permuting
those characters, and restoring the objects via dictionary
lookup:

    def ultra_perm(objs):
        if len(objs)>10:
            raise ValueError,"To big to handle"
         index = 0
         permdict = {}
         for o in objs:
            permdict[str(index)]=o
            index += 1
         perms = perm(permdict.keys())
         output = [tuple([permdict[entry] for entry in p]) \
                  for p in perms]
         return output

(code for perm() in earlier post).

Now you can go:

   >>> ultra_perm(range(3))
   [(1, 0, 2), (1, 2, 0), (2, 1, 0), (2, 0, 1), (0, 2, 1),
   (0, 1, 2)]

Or even:

   >>> ultra_perm(['a1',2,['a',1]])
   [(2, 'a1', ['a', 1]), (2, ['a', 1], 'a1'),
   (['a', 1], 2, 'a1'), (['a', 1], 'a1', 2),
   ('a1', ['a', 1], 2), ('a1', 2, ['a', 1])]

The original perm() function failed for multicharacter
strings, e.g. perm(('x1','x2')) returned:

    >>> perm(['x1','x2'])
    [['x1', 'x', '2'], ['x2', 'x', '1']]

Clearly not what's intended.

A version of your listify() rectifies this problem:

    def listify(obj):
        """
        Prevent breakdown of string objects, into
        lists of characters, with thanks to
        Andrew Wilkins
        """
         if type(obj)==type(''):
            return [obj]
         else: return list(obj)

    def perm(set):
        """
        Return all permutations of a set.  Thanks to
        Daniel Ajoy for sharing his Logo version with me.
        """

        if len(set)==0:  return []
        if len(set)==1:  return set

        answ = []

        for i in range(len(set)):
            base = [set[0]]
            rest = set[1:]
            answ = answ + [base + listify(i) for i in perm(rest)]
            set = [set[-1]]+set[:-1]

        return answ

With this modification, we can go:

   >>> perm(['x1','x2'])
   [['x1', 'x2'], ['x2', 'x1']]

With this modification in place, it's now possible, even if
impractical, to go beyond the 10 object limit in ultra_perm.

Kirby