[Tutor] permutations?

Steven D'Aprano steve at pearwood.info
Fri Dec 3 01:32:59 CET 2010


Alan Gauld wrote:
> 
> "Alex Hall" <mehgcap at gmail.com> wrote
> 
>> Alright, I have it working. Now the problem is that it does not throw
>> out reversals. I tried to do this myself with a couple loops, but I
>> get index errors. My total list of permutations is called l.
>>
>> for i in range(0, len(l)):
>> r=l[i]; r.reverse()
> 
> You don''t need to specify the 0, its the default.
> But you don't need to use indexing either.
> 
> for r,i in enumerate(l): r.reverse()
> 
>> for j in range(0, len(l)):
>>  print l[j], r, i, j
> 
> Here you are comparing the reversed item to every item in the
> list, including the ones you have already reversed, including the
> item itself. So you will always find a match when i==j...
> 
> Using the in operator and list slicing would be easier
> 
> if r in l[i:]: l.remove(r)
> 
> but...
> 
>>  if r==l[j]: l.remove(r)
> 
> Its never a good idea to remove items from a list you are iterating
> over, its like the old cartoon of the guy cutting down the tree branch
> he is sitting on. 

You can cut off the branch you're sitting on so long as you remember to 
cut on the correct side :)

Back in Ancient Days when dinosaurs walked the earth, and I programmed 
in Pascal, computers didn't have much memory, and were slow. 
Consequently it wasn't practical to make a copy of a list if you wanted 
to delete a few items. The only practical way to modify lists was to 
modify them in place, and if you needed to delete items, you had to work 
backwards. It took me a while to break myself of the habit of doing this:

for i in range(len(mylist)-1, -1, -1):
     if mylist[i] == "something":
          del mylist[i]

(Note that you only need to work backwards if you're *deleting* entries, 
not if you replace them with something else.)

This is still a useful technique to have in your toolbox, but generally 
speaking the above is better written as:

mylist = [x for x in mylist if x != "something"]


If you really need to modify the list in place, and not just re-bind the 
name "mylist" to the new list, then one tiny change will do it:

mylist[:] = [x for x in mylist if x != "something"]



-- 
Steven



More information about the Tutor mailing list