我试图找到那个问题的答案,但找不到合适的关键字......
我想知道如何在类的实例中创建值(value)帮助列表。 我不想要的是:
class Test:
def __init__(self,i)
self.i = i
inst1 = Test(2)
inst2 = Test(5)
MyList = [inst1.i,inst2.i]
此时 MyList = [2,5] 如果我更改值 if inst1
inst1.i = 4
print MyList
[2,5]
MyList 仍然是 [2,5],但我希望它更新为 [4,5]
print MyList
[4,5]
所以我的问题是,如何创建一个指向变量而不是变量值的列表?
如果您想知道原因:我正在运行蒙特卡洛模拟,其中我有很多蛋白质,每个蛋白质都有一个能量值,并且每个蛋白质都是从蛋白质类实例化的。
class Protein:
def __init__(self,sequence,energy):
self.sequence = sequence
self.energy = energy
某些蛋白质的能量值在蒙特卡洛模拟期间得到更新。我需要一份所有能量的列表来对分布进行一些计算。没错,我用 for 循环更新了列表,但如果我有一个指向变量的列表,效率会更高,这样每次 Protein 类中的能量发生变化时,列表都会自动更新。
非常感谢!
最佳答案
一个很好的问题。
通往您答案的两个要点:
- 经典变量与 python 类标签“变量”/标识符
- 可变 vs 不可变 python 类型
您必须记住,如果您来自另一种编程语言,在 Python 中名称 variable 可能会产生误导。最好不要谈论变量,而是谈论“标签”。
当你创建一个像这样的对象时:myvar = 1
你创建(过度简化)了一个对象 1
并且为了跟踪它你附加了一个标签 myvar
给它。
因此,如果您想谈论对象 1
,您可以说:“The object labeled with 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]
所以你现在有一个包含 2 个不可变对象(immutable对象)的列表! 您的下一步:
inst1.i = 4
创建一个新对象 4
并将 inst1.i
标签 重新附加到它上面!您刚刚丢失了对象 2
的句柄。但是因为它在 MyList
集合中,所以它仍然被引用并且不会被垃圾收集。
现在进入要点 2:
一个不错的overview of mutable and immutable对象,表明基本上所有原始类型都是不可变的,大多数集合是可变的。区别在于。可变对象可以就地编辑,而不可变对象(immutable对象)需要替换。
或者保持标签的逻辑:在不可变对象(immutable对象)上你需要移动“标签”,而在可变对象上你需要将“标签”保持在适当的位置并将对象移动到它下面。
现在回到你的问题:
基本上你需要改变视角! MyList
不是一个数组,而是一个集合。因此,为了不重新发明您的解决方案场所,我建议将 Test
对象保留在您的列表中,而不是它们的值!:
MyList = [inst1,inst2]
如果您现在更改 inst1.i = 4
,将发生以下情况:
- 您创建对象
4
- 您将属性 inst1.i 附加到它(“重新标记”它)
- 您的对象成为列表和您的新对象之间的中介
- 您可以通过
MyList[0].i
或inst1.i
访问4
任务完成! ;-)
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]
关于 python : How to create a dynamic list of class values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20531168/