[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