2

I've been working on the code shown below for udacity. I'm trying to figure out why the lists 'g' and 'p' are acting as the same list when 'g' is created by calling list(p). When the print statement (print[i][j]) is called in the move function it shows that 'p' is being overwritten when 'g' is changed. I just started programming in python and I would appreciate any help. Thanks in advance.

    colors = [['red', 'green', 'green', 'red' , 'red'],
      ['red', 'red', 'green', 'red', 'red'],
      ['red', 'red', 'green', 'green', 'red'],
      ['red', 'red', 'red', 'red', 'red']]

    measurements = ['green', 'green', 'green' ,'green', 'green']


    motions = [[0,0],[0,1],[1,0],[1,0],[0,1]]

    sensor_right = 0.7

    p_move = 0.8

    def show(p):
        for i in range(len(p)):
             print p[i]


    total = len(colors[0])*len(colors)
    for i in range(len(colors)):
        p.append([])
        for j in range(len(colors[i])):
            p[i].append(1./total)
    print p

    def move(g,c,r):
        t = list(g)
        for i in range(len(g)):
            for j in range(len(g[i])):
                print p[i][j]
                t[i][j] = t[(i-c)%len(g)][(j-r)%len(g[i])] * p_move
                print p[i][j]
        s = sum_table(t)
        for i in range(len(g)):
            for j in range(len(list(g[i]))):
                t[i][j] /= s
        return t 

    def sum_table(g):
        sum = 0
        for i in range(len(g)):
            for j in range(len(g[i])):
                sum += g[i][j]
        print sum
        return sum


    move(list(p),0,1)
    print p
Jimmy
  • 65
  • 7
  • Why do you think you need to do all this copying? Well-written Python code usually avoids deliberate copying. Instead of making a copy and then changing it, write code that directly creates the changed version. – Karl Knechtel Apr 02 '12 at 01:22
  • P.S. The effect of multiplying everything by `p_move` is cancelled out by the normalization step, which is unnecessary if you just start with normalized data in the first place. Also, since `p` starts out with the same `1./total` value in every place, you're not going to see a difference after "rotating" the array. – Karl Knechtel Apr 02 '12 at 01:33
  • It was more of a frustration that my code wasn't working as anticipated. I realize that I don't need to do copying as I have done, but I got to where I couldn't figure out the problem and I wanted to know why it was wrong. As for p_move, this is necessary to describe the error of movement. The normalization step will change the array as I cycle through sensor readings of green or red. This code wasn't near completion and there wasn't a point of rotating the array, but as "movements" and "readings" occur the distribution will change. I am trying to implement linearization. – Jimmy Apr 02 '12 at 03:51
  • P.S. I see your point on p_move, I meant to also have a component where the movement error is factored in. Thanks for pointing that out. In my code above, multiplying by p_move really does nothing. – Jimmy Apr 02 '12 at 04:00
  • *localization (not linearization) – Jimmy Apr 02 '12 at 05:18

1 Answers1

7

I haven't followed through your code in detail, but the source of your trouble is likely the use of two dimensional data structures (lists of lists). In Python, the list() constructor is a shallow copy, which only copies one level of list. You may be able to avoid the problem you're seeing using the copy.deepcopy() function where appropriate.

One trick is to use id(p) and id(g) to find out what the actual object identity is for each reference. This sort of debugging may help isolate your problem. You're calling the list() constructor a lot, probably much more than necessary. Creating unnecessary copies of data structures like this will make much more work for the CPU and can affect performance critical code.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Thank you very much! I was using id to find out the actual object identity, but I did not realize the list() constructor was not recursive and that essentially I had two separate lists pointing to the same sets of lists. Now that makes sense. – Jimmy Apr 02 '12 at 00:49
  • @aaronasterling, thanks for the suggestion. I've accepted it as best now. – Jimmy Apr 02 '12 at 03:47