Python is not iterating through range() list as I expected

Issue

I am still learning the ins and outs of Python, and have hit a stumbling block.

I am trying to create an n^2 sized grid of objects that hold data corresponding to their (x,y) coordinates on the grid, but when I try to iterate through the grid as a 2d array, it somehow just assigns all coordinates with the max n value. I think I am missing a fundamental concept regarding how Python iterates through lists and how to use them in for-loops. Here is the object:

 class Node:
     def __init__(self,x,y):
         self.x = x
         self.y = y

     def pos(self,x,y):
         self.x = x
         self.y = y

And here is the grid. For simplicity’s sake, I set n=10:

 class Stage:

     bg = ([([comp.Node(0,0)] * 10)] * 10)

     def drawNodes(self):
         for x in range(10):
             for y in range(10):
                 self.bg[x][y].pos(x,y)

 stage1 = Stage()

When I run the drawNodes() function, it seems to assign all Node objects with the x & y values of 9. What bit of logic am I missing here? Thank you to anyone with advice!

Solution

The problem is this bg = ([([comp.Node(0,0)] * 10)] * 10) puts a reference to the same object into all entries. Try out this code to see the effect

a = [[{}]*3]*3
a[0][0]["a"] = 100

which results in [[{'a': 100}, {'a': 100}, {'a': 100}], [{'a': 100}, {'a': 100}, {'a': 100}], [{'a': 100}, {'a': 100}, {'a': 100}]]

Try to initialize bg like this

bg = [[comp.Node(0,0) for _ in range(10)] for _ in range(10)]

This will create 100 different objects and not just put a reference to the same object into different positions of your lists

Answered By – Simon Hawe

Answer Checked By – Katrina (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.