# [Tutor] buggy bug in my program

Kent Johnson kent37 at tds.net
Sun Jun 11 12:58:39 CEST 2006

```Kermit Rose wrote:
> # def insertw(j1,k,w1,w2,jar,limit):
> #    trace = 1
> #    if k == 0:
> #        jar[k][0] = k
> #        jar[k][1] = w1
> #        jar[k][2] = w2
> #        return
> #    if j1 > k:
> #        jar[j1][0] = k
> #        jar[j1][1] = w1
> #        jar[j1][2] = w2
> #        return
> #
> #    for j2 in range(j1+1,k+1):
> #        j3 = k + j1 - j2
> #        if trace > 0:
> #            print " insertw:  move jar[",j3,"] up one"," j1 = ",j1," k = "
> k," w1 = ",w1," w2 = ",w2
> #        f = jar[j3]
> #        jar[j3+1] = f

I think you want to copy jar[j3] here. In your code, jar[j3] and
jar[j3+1] both refer to the same list! If you change the list, you will
see it in both places.

Assignment in Python is not a copy, it is a name binding. Assignment
creates a name for an object. If you assign the same object to two
names, they both are bound to the same thing. If the object is mutable,
like a list, changes to the object will be seen regardless of which name
you use to refer to it.

For example:
In [14]: d = [1, 2, 3]

In [15]: e=d

d and e are now references to the same list

In [18]: d[0]=55

The changes the list, the change can be seen regardless of which
reference to the list is used to access it.
In [19]: d
Out[19]: [55, 2, 3]

In [20]: e
Out[20]: [55, 2, 3]

Here is one way to make a copy; d and f refer to different lists:
In [21]: f=d[:]

In [22]: f
Out[22]: [55, 2, 3]

Changing f doesn't affect d or e:
In [23]: f[1]=23

In [24]: f
Out[24]: [55, 23, 3]

In [25]: d
Out[25]: [55, 2, 3]

In [26]: e
Out[26]: [55, 2, 3]

This may help:
http://www.effbot.org/zone/python-objects.htm

Kent

> #        if trace > 0:
> #            print " insertw: jar[",j3+1," is now ",jar[j3+1]
> #
> #
> #    jar[j1][0] = k
> #    jar[j1][1] = w1
> #    jar[j1][2] = w2
> #
> #    if trace > 0:
> #        for j in range(k+1):
> #            print " insertw: jar[",j,"] = ",jar[j]
> #    return
> #
>
>
> debug trace shows the following puzzling behavior.
>
>
> fermat2: before insertw:  jar[ 0 ] =  [0, 2, 4]
>  fermat2: before insertw:  jar[ 1 ] =  [1, 4, 16]
>  fermat2: before insertw:  jar[ 2 ] =  [-1, -1, -1]
>
>
> I show the array jar before going into insert.
>
> remember the heading of  insertw is
>
> # def insertw(j1,k,w1,w2,jar,limit):
>
>
>
>  insertw:  move jar[ 1 ] up one  j1 =  1  k =  2  w1 =  16  w2 =  13
>
> This shows that insert made one shift, and sifted jar[1] to jar[2].
> j1 = 1 means that insertw was supposed to insert new value into jar[1]
>
>  insertw: jar[ 2]  is now  [1, 4, 16]
>
> I print out jar[2] to show that insertw really did shift jar[1] to jar[2].
>
>
>
>
>  insertw: jar[ 0 ] =  [0, 2, 4]
>  insertw: jar[ 1 ] =  [2, 16, 13]
>  insertw: jar[ 2 ] =  [2, 16, 13]
>
> Now, outside the loop,
> I  set jar[j1] to the new values.
>
> And I print the resulting array, still within the routine insertw.
>
> jar[1] has been set to the new values.
>
> BUT, and this is the problem,
>
> jar[2] has been also set to the new values.
>
> WHY???????????
>
>
>
>
>
>
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
>

```