Permutations with generators
Dan Bishop
danb_83 at yahoo.com
Sat Jul 21 02:05:10 EDT 2007
On Jul 21, 12:42 am, Pablo Torres <tn.pa... at gmail.com> wrote:
> Hey guys!
> For the last couple of days, I've been fighting a war against
> generators and they've beaten the crap out of me several times. What I
> want to do is implement one that yields every possible permutation of
> a given sequence (I had lists in mind, but I could swear that this
> would work on strings too...if it worked at all).
>
> Here's what I have so far:
>
> def perm(seq):
> "Reshuffles the elements of seq in every possible way"
> if len(seq) == 1:
> yield seq
> else:
> for p in perm(seq[1:]):
> for i in range(len(seq)):
> yield p.insert(i, seq[0])
>
> Basically, I let the recursion reshuffle the elements of the
> subsequence that starts from the second element of the original one,
> and then I insert seq[0], the first element of the original sequence,
> in every position of the shuffled sublist.
>
> Here's what I get when I try to list the permutations of [1, 2, 3, 4]
> (print list(perm([1, 2, 3, 4]))):
>
> Traceback (most recent call last):
> File "perm.py", line 15, in <module>
> print list(perm([1, 2, 3, 4]))
> File "perm.py", line 11, in perm
> for p in perm(seq[1:]):
> File "perm.py", line 13, in perm
> yield p.insert(i, seq[0])
> AttributeError: 'NoneType' object has no attribute 'insert'
>
> Could somebody please explain to me why my p variable has no type at
> all?
> For every call to perm(seq), seq should always be of the same type as
> the sequence that was used in the first call. Any ideas as to where
> seq loses it's type?
list.insert returns None. Thus, except in the one-element case, your
generator is yielding None all the time.
Try this:
def permutations(seq):
if len(seq) == 1:
yield seq
else:
for i, x in enumerate(seq):
for perm in permutations(seq[:i] + seq[i+1:]):
yield [x] + perm
More information about the Python-list
mailing list