help with something that ought to be simple

Paul Sidorsky paulsid at home.com
Thu Oct 25 03:15:35 CEST 2001


Matthew Nobes wrote:

> def del_2(rho,input,output):
> 
>     output=[[0,0,0,0]]

First off, output is unnecessary as a parameter since you return it later. 
There's no need to provide output as a "buffer" like in other languages.  In
fact you can't do this; the assignment to output will just rebind the name
output to something else without affecting the name of the original object
(whatever was passed in).  Simply do output = del_2(a, b) and it will work
fine.

> 
>     for i in input:
>         i[rho-1]=1

Here's a problem, though it's not the one described.  You are working on the
items of input itself.  Try printing input after this loop.  Notice how it has
changed!  And unlike above, this time you're changing the items of i so the
changes WILL make it back to the original object!  If you're throwing away
input (e.g. replacing it with output) this won't matter but otherwise you'll
want to use a copy of input:

    for i in list(input):
or
    for i in input[:]:

Either makes a copy of input and operates on that.  (I prefer the former but I
think it only works in 2.x Python versions; the latter works in earlier ones.) 
It's probably better coding style to make the copy and avoid changing the input
even if you won't be using it later, because you never know when you'll want to
change your mind.

>         output.append(i)

This is what's causing the described behaviour.  It should be:

        output.append(list(i))
or
        output.append(i[:])

In Python everything is done by references so you are appending a reference to
the old object to your list rather than a new object.  Again you need to append
a copy to avoid altering the original later.

>         temp.append(i)
>         output.append(i)

These should be similarly altered as above.

> Now I did this to temp.  So I should be able to now append this
> to output and my result *SHOULD* be
> [[0,0,0,0],[0,1,0,0],[1,1,0,0],[1,0,0,0]]

The change I just described does indeed produce this output.

> but instead the operation on temp also gets preformed on output
> and I get
> [[0,0,0,0],[0,1,0,0],[1,0,0,0],[1,0,0,0]]

If you're not convinced as to why this happens and why the above fixes it, try
this:

a = [0,0,0,0]
b = [0,1,0,0]
output = [a, b, a]
a[0] = 1           # Changes both a and items 0 and 2 of output
output[0][1] = 2   # Also changes items 0 and 2 of output & a.
a = [0,1,1,1]      # Now a is different but items 0 and 2 of output
                   # still exist and are the same old list.

This behaviour is annoying at first but once you get used to it you can exploit
it for a lot of neat tricks.

Hope that helps.

-- 
======================================================================
Paul Sidorsky                                          Calgary, Canada
paulsid at home.com                      http://members.home.net/paulsid/




More information about the Python-list mailing list