Xqu*_*qua 5 python class list dynamic
我试图找到该问题的答案,但是我找不到好的关键词...
我想知道如何在类实例中创建值帮助列表。我不想要的是:
class Test:
def __init__(self,i)
self.i = i
inst1 = Test(2)
inst2 = Test(5)
MyList = [inst1.i,inst2.i]
Run Code Online (Sandbox Code Playgroud)
那时,如果我更改了inst1的值,则MyList = [2,5]
inst1.i = 4
print MyList
[2,5]
Run Code Online (Sandbox Code Playgroud)
MyList仍然为[2,5],但我希望将其更新为[4,5]
print MyList
[4,5]
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,如何创建一个指向变量而不是变量值的列表?
如果您想知道为什么:我正在运行MonteCarlo模拟,其中我有很多蛋白质,每种蛋白质具有一个能量值,并且每种蛋白质都从Protein类中实例化。
class Protein:
def __init__(self,sequence,energy):
self.sequence = sequence
self.energy = energy
Run Code Online (Sandbox Code Playgroud)
一些蛋白质的能量值会在蒙特卡洛模拟中更新。我需要一个所有能量的列表来对分布进行一些计算。知道,我使用for循环更新了列表,但是如果我可以有一个指向变量的列表,那将更加有效,这样每次Protein类中的能量更改时,列表都会自动更新。
非常感谢 !
这是一个很好的问题。
回答您的问题时有两个要点:
你必须记住,在 python 中,如果你来自另一种编程语言,名称变量可能会产生误导。也许最好不要谈论变量,而是谈论“标签”。
当您创建一个对象时,例如:myvar = 1您创建(过于简单化)一个对象1并在其上附加一个标签来跟踪它myvar。因此,如果您想谈论该对象,1您可以说:“标有 的对象myvar。” 您可以通过重新标记将标签重新附加到另一个对象:myvar = 2。如果myvar这是你身上唯一的标签,1你刚刚丢失了该对象1,它将被垃圾收集。
在你的情况下:
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]
Run Code Online (Sandbox Code Playgroud)
现在你有了一个包含 2 个不可变对象的列表!您的下一步:
inst1.i = 4
Run Code Online (Sandbox Code Playgroud)
创建一个新对象4并将inst1.i 标签重新附加到它上面!你刚刚失去了对 object 的控制2。但因为它在MyList集合中,所以仍然被引用并且不会被垃圾收集。
现在进入要点 2:
对可变和不可变对象的一个很好的概述表明,基本上所有原始类型都是不可变的,并且大多数集合都是可变的。区别在于。可变对象可以进行就地编辑,而不可变对象需要被替换。
或者保持标签的类比:在不可变对象上,您需要移动“标签”,而在可变对象上,您将“标签”固定在适当的位置并将对象移动到其下方。
现在回到你的问题:
基本上你需要改变观点!MyList不是数组,而是集合。因此,为了不重新发明您的解决方案,我建议将对象保留Test在列表中,而不是它们的值!:
MyList = [inst1,inst2]
Run Code Online (Sandbox Code Playgroud)
如果您现在进行更改inst1.i = 4,则会发生以下情况:
44通过MyList[0].i或访问inst1.i任务完成!;-)
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]
Run Code Online (Sandbox Code Playgroud)