I have tried to find the anwser to that question, but I cannot find the good Keywords ...
I want to know how can I create a list of value help in instances of a class. What I do not want is that :
class Test:
def __init__(self,i)
self.i = i
inst1 = Test(2)
inst2 = Test(5)
MyList = [inst1.i,inst2.i]
At that point MyList = [2,5] if I change the value if inst1
inst1.i = 4
print MyList
[2,5]
MyList is STILL [2,5] but I want it to be updated to [4,5]
print MyList
[4,5]
So my question is that, how do I create a list that points to the variable and not the variable value ?
If you want to know why : I am running a MonteCarlo simulation in which I have a lot of proteins, each with one energy value, and each Protein is instantiated from a Protein class.
class Protein:
def __init__(self,sequence,energy):
self.sequence = sequence
self.energy = energy
That energy value of some proteins gets updated during a montecarlo simulation. I need a list of all the energies to perform some calculation on the distribution. Right know, I updated the list with a for loop, but it would be way more efficient if I could have a list that points to the variable, that way every time an energy in the Protein class is changed the list is updated automatically.
Thanks a lot !
A very good question.
Two bullet-points on the way to your answer:
You have to keep in mind, that in python the name variable may be misleading if you come from another programing language. It may be better not to talk about variables, but about "labels".
When you create an object like: myvar = 1
you create (oversimplification) an object 1
and to keep track of it you attached a label myvar
to it.
So if you want to talk about the object 1
you could say: "The object labeled with myvar
." You may reattach the label to another object by relabeling: myvar = 2
. If myvar
was the only label on 1
you just lost the object 1
and it will be garbage collected.
In your case:
inst1 = Test(2) # create 2 and attach it to inst1.i
inst2 = Test(5) # create 5 and attach it to inst2.i
MyList = [inst1.i,inst2.i] # list of objects: [2 ,5]
So you now have a list of 2 immutable objects! Your next step:
inst1.i = 4
creates a new object 4
and reattaches the inst1.i
label onto it! You just lost your handle on object 2
. But because it's in the MyList
collection it's still referenced and won't be garbage collected.
Now on to bullet point 2:
A nice overview of mutable and immutable objects, shows that basically all primitive types are immutable and most collections are mutable. The difference is. that mutable objects can get an in-place edit, while immutable objects need to be replaced.
Or to keep the label anology: On immutable objects you need to move the "Label" while on mutable you hold the "Label" in place and move the object under it.
Now back to your problem:
Basically you need to change perspective! MyList
is NOT an Array, but a collection. So in order not to reinvent your venue of solution i would recommend to keep the Test
objects in your list, rather than their values!:
MyList = [inst1,inst2]
If you change now inst1.i = 4
, the following happens:
4
4
over MyList[0].i
or inst1.i
Mission accomplished! ;-)
for value in MyList:
print value.i
inst1.i = 4
raw_values = [o.i for o in MyList]
[4, 5]
inst1.i = 2
raw_values = [o.i for o in MyList]
[2, 5]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With