0

It would appear that two objects are sharing the same non-static/non-global variable and I am confused how that is possible, see below:

class Pop:
    def __init__(self):
        self.n = 2
        self.w = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
        self.w_min = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        self.w_max = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

    def populate(self, __run):
        for i in range(self.n):
            self.varients.append(Varient(self))
            for x in range(len(self.varients[i].w)):
                self.varients[i].w[x] = randint(self.varients[i].w_min[x] * 100,
                                                        self.varients[i].w_max[x] * 100) / 100
                    else:
                        self.varients[i].w[x] = randint(self.varients[i].w_min[x] * 100,
                                                        self.varients[i].w_max[x] * 100) / 100
            print(self.varients[i].w)
        print(self.varients[0].w)
        print(self.varients[1].w)
        for x in range(len(self.varients[1].w)):
            self.varients[1].w[x] = 1
        print(self.varients[0].w)
        print(self.varients[1].w)


class Varient(Pop):
    def __init__(self, parent):
        super().__init__()

        self.w = parent.w
        self.w_min = parent.w_min
        self.w_max = parent.w_max

This is the output I see:

[1.0, 1.0, 0.86, 0.685, 0.925, 0.735, 0.35, 0.825, 0.31, 0.62, 0.71, 0.88]
[1.0, 1.0, 0.565, 0.575, 0.95, 0.405, 0.605, 0.48, 0.42, 0.445, 0.745, 0.41]
[1.0, 1.0, 0.565, 0.575, 0.95, 0.405, 0.605, 0.48, 0.42, 0.445, 0.745, 0.41]
[1.0, 1.0, 0.565, 0.575, 0.95, 0.405, 0.605, 0.48, 0.42, 0.445, 0.745, 0.41]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

When I change the value of "w" for object "self.varients[1]" it somehow changes the value of "self.varients[0]". If I was passing pointers arround this would make sense to me, but I don't understand why this is happening?

BRobs
  • 3
  • 2
  • Lists are mutable if thats the actual problem. – What Apr 27 '18 at 22:31
  • This code is not valid syntax (the indentation is off), nor is there a way to run it to see the problem ourselves. Please provide a [mcve]. – Alex Hall Apr 27 '18 at 22:32
  • 1
    `self.w = parent.w` doesn't make a new list. See https://nedbatchelder.com/text/names.html – user2357112 Apr 27 '18 at 22:33
  • 2
    What you did is `self.w = parent.w`. That means that `self.w` is now another reference for the same object `parent.w` references. So yes, you just created another name for the exact same object. You need to create a copy. This can be done a few different ways: `parent.w[:]`, `parent.w.copy()`, `list(parent.w)`, etc. – zondo Apr 27 '18 at 22:33
  • I added another duplicate that explains pass by assignment. – zondo Apr 27 '18 at 22:36
  • Python doesn't have pointers, but if you are familiar with pointers, you can think of all Python variables as Python object pointers. I second the recommendation to read https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Apr 28 '18 at 01:20

0 Answers0