[Tutor] Basic Question

Cameron Simpson cs at cskk.id.au
Thu Sep 9 09:20:41 EDT 2021


On 08Sep2021 23:50, Osmaan Mysorewala <osmaan at mysorewala.com> wrote:
>I'm trying to write a python program to create the game of life (Here's 
>the
>wikipedia link to how the game of life works:
>https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life). Right now it works
>only for the first iteration but then the new_arr becomes something
>completely wrong the second time I run the function. I think something is
>logically wrong with the neighbors function (other than how badly the
>if-statements are written). [...]

I don't think so. Since the first run looks ok, the neighbors function 
is probably correct or close to correct. And anyway it looks right to 
me.

I suspect this:

    old_arr = new_arr.copy()

This is a shallow copy. Your arrays are nested lists of lists. A shallow 
copy copies the outer list, but not  the inner lists. Since all values 
are actually references this means the copy is a new list, containing 
references to the old lists. When you make your pass over the old array 
an set the values in the new array, on the second pass you're actually 
updating the inner lists in the old array.

Before the first pass you've got (scaled down as 2x2 and broken out into 
distinct setups:

    old1 = [0, 0]
    old2 = [0, 0]
    old_arr = [old1, old2]
    new1 = [0, 0]
    new2 = [0, 0]
    new_arr = [new1, new2]

2 completely distinct lists of lists.

After the:

    old_arr = new_arr.copy()

action you've got a new list "old_arr" with a copy of new_arr, but only 
a copy of its elements:

    old_arr = [new1, new2]

a new list, but pointing at the _original_ "new1" and "new2" lists. So 
now your arrays are:

    old_arr = [new1, new2]
    new_arr = [new1, new2]

and when you walk old_arr (correctly) and the modify things in new_arr, 
you're modifying new1 or new2, and they _are_ the contents of old_arr - 
so you've changed the original array while you're examining it. Your 
neighbor calculations will then be incorrect.

A better approach might be this:

    old_arr = new_arr
    new_arr = [[0 for i in range(cols)] for j in range(rows)]

i.e. make old_arr point at the new grid you just computed, and create a 
shiny new grid to use as "new_arr" for the next pass.

Remember, Python variables are references to values. An assignment just 
moves a reference.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Tutor mailing list