1

I am trying to run a random walk on a two-dimensional grid with four equiprobable actions [right(1), left(-1), upward(1), downward(-1)]. As the random walker moves forward, I want to store its location (x, y coordinates) in the list totSteps. The x,y coordinates (that is, current location) will be updated on every step as a variable curr_loc. As you can see in the printed output, the first list (curr_loc) is the updated current location, and the second list (totSteps) supposedly contains the steps taken so far. There were 5 steps taken, and as such we have 10 outputs. Every time I append the curr_loc to totSteps; all the previous coordinates get replaced with the current one. What's the reason?

steps = [1,-1,1,-1]
totSteps = [] # stores all the 5 steps taken but doesn't work 
# random walk with four steps left, right, 
# upward, downward on two dimensional grid
curr_loc = [0,0]
N = 5
for i in range(N):
 ranNums = np.random.randint(0,4) # picks one of four actions 
 if ranNums == 0 or ranNums == 1: # change x-coordinate
 curr_loc[0] += steps[ranNums] # taking the step 
 print(curr_loc) # current location of random walker 
 totSteps.append(curr_loc)
 print(totSteps) # append current location of random walker 
 elif ranNums == 2 or ranNums == 3: # chanfe y-coordinate 
 curr_loc[1] += steps[ranNums]
 print(curr_loc)
 totSteps.append(curr_loc) 
 print(totSteps)

The output of the code is given below:

>[1, 0] # curr_loc
>[[1, 0]] # totSteps
>[1, -1]
>[[1, -1], [1, -1]]
>[1, 0]
>[[1, 0], [1, 0], [1, 0]]
>[1, -1]
>[[1, -1], [1, -1], [1, -1], [1, -1]]
>[0, -1]
>[[0, -1], [0, -1], [0, -1], [0, -1], [0, -1]]
asked Apr 24, 2022 at 19:58
3
  • 1
    You're appending the same curr_loc to the list every iteration. Try totSteps.append(curr_loc[:]) Commented Apr 24, 2022 at 20:02
  • Thanks. It works. When I print curr_loc in the iteration, it prints out the updated value. I still don't understand why all previous values get replaced with the current value. Python append method appends the value (or list) to the end of list. Commented Apr 24, 2022 at 20:11
  • 2
    @fireshadow52's answer is good at explaining it :) Basically, you're adding the same one reference to the output list, so any change to any of the list affects all other lists. Commented Apr 24, 2022 at 20:13

1 Answer 1

2

To further expand on @AndrejKesely's answer, you're not defining a new list object when a new loop iteration starts, and so whenever you change the values in curr_loc, since you're essentially appending another reference to curr_loc to totSteps, you have five references to the same object and that's why you're getting the same values.

Andrej's solution of curr_loc[:] means that you're effectively making a copy of the entire list and storing that rather than a reference to curr_loc.

answered Apr 24, 2022 at 20:08
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your explanation. I had never faced this issue before. I don't have much experience, but I think the concept of reference is common in C++. I will look into it further.
No worries! Yes, "pass-by-value" and "pass-by-reference" are common in C++ as well, but there it's a bit more obvious when a function parameter is a reference parameter.
Yes. I need to look into it closely. I spent so much time figuring out the issue.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.