第一篇文章,所以玩得很好!
我有一个关于Python词典的相当基本的问题。我希望有一些dict值在另一个变量被更改时更新(或者至少在下次调用时重新计算) - 例如:
mass = 1.0
volume = 0.5
mydict = {'mass':mass,'volume':volume}
mydict['density'] = mydict['mass']/mydict['volume']
所以在这种情况下,mydict ['density']只返回2.0。如果我改变mydict ['mass'] = 2.0,密度将不会更新。很好 - 我可以理解为什么 - 密度是由传递给声明时的值定义的。所以我想也许我可以用lambda表达式来解决这个问题,例如(为可怕的代码道歉!):
mydict['density_calc'] = lambda x,y: x/y
mydict['density'] = mydict['density_calc'](mydict['mass'],mydict['volume'])
但同样,这只会返回原始密度,尽管改变了mydict ['mass']。作为最后的尝试,我尝试了这个:
def density(mass,volume): return mass/volume
mydict['density_calc'] = lambda x,y: density(x,y)
mydict['density'] = mydict['density_calc'](mydict['mass'],mydict['volume'])
再次,没有骰子。这似乎是一个非常简单的问题需要解决,所以提前道歉,但如果有人能帮助我,我会非常感激!
干杯,
戴夫
答案 0 :(得分:9)
似乎是滥用字典结构。为什么不创建一个简单的类?
class Entity(object):
def __init__(self, mass, volume):
self.mass = mass
self.volume = volume
def _density(self):
return self.mass / self.volume
density = property(_density)
答案 1 :(得分:6)
在这种情况下,最好为此创建一个类并使用动态属性。 e.g:
class Body(object):
def __init__(self):
self.mass=1.0
self.volume=0.5
@property
def density(self):
return self.mass/self.volume
这将为您提供质量,体积和密度属性,其中密度是根据其他两个值计算的。 e.g。
b=Body()
b.mass=1
b.volume=0.5
print b.density # should be 2
b.mass=2.0
print b.density # should be 4
但是,如果你坚持使用字典,你应该扩展它并覆盖__getitem__
和__setitem__
“魔法”方法,以及检测质量何时发生变化,或者当密度被访问时根据需要重新计算。
答案 2 :(得分:4)
一个班级会做得更好:
class Thing:
def __init__(self, mass, volume):
self._mass = mass
self._volume = volume
self._update_density()
def _update_density(self):
self._density = self._mass / self._volume
def get_density(self):
return self._density
density = property(get_density)
# You're unlikely to need these, but to demonstrate the point:
def set_mass(self, mass):
self._mass = mass
self._update_density()
def set_volume(self, volume):
self._volume = volume
self._update_density()
brick = Thing(mass=2, volume=0.8)
print brick.density
# Prints 2.5
brick.set_mass(4)
print brick.density
# Prints 5.0
我告诉你,当你设置其他值时,你想要更新密度 - 更简单的方法就是在被要求时简单地计算它:
def get_density(self):
return self._mass / self._volume
然后你根本不需要_update_density()
。
答案 3 :(得分:3)
简短的回答是你不能。
分配的表达式在遇到时会被strictly评估,因此以后对这些术语的任何更改都无关紧要。
您可以使用自定义dict类来覆盖 getitem 和 setitem 方法并为某些键执行特殊操作(即计算值)(比如说)密度和有限数量的其他)。
class MyDict(dict):
def __getitem__(self, key):
if key == "density":
return self["mass"] / self["volume"]
return dict.__getitem__(self, key)
d = MyDict()
d["mass"] = 2.0
d["volume"] = 4.0
d["density"] # 0.5
查看this。
答案 4 :(得分:3)
问题是词典不是解决问题的正确工具。你的问题就像“我怎么能用螺丝刀敲钉子”; - )
字典应该将键映射到值,而不关心字典中的其他值。你想要的是一个班级
class PhysicalObject:
def __init__(self, mass, volume):
self.mass = float(mass)
self.volume = float(volume)
def setMass(self, mass):
self.mass = float(mass)
def setVolume(self, volume):
self.volume = float(volume)
def getDensity(self):
return self.mass/float(self.volume)
v = PhysicalObject(1.0, 2.0)
print v.getDensity() # prints 0.5
v.setMass(2.0)
v.setVolume(1.0)
print v.getDensity() # prints 2.0
此示例每次您想要获取密度时重新计算密度,购买时您也可以在setMass和setVolume函数中计算它。
答案 5 :(得分:1)
这很容易:
>>> mydict = {'mass':100, 'volume': 2, 'density': lambda: mydict['mass']/mydict['volume']}
>>> mydict['density']()
50
>>> mydict['mass']=200
>>> mydict['density']()
100
>>> mydict['volume'] = 4
>>> mydict['density']()
50
我的lambda引用了mydict,后来又在mydict中检索了最新的数据保存,所以每次我想调用它时都不会将质量和音量传递给函数,就像你的解决方案一样:
def density(mass,volume): return mass/volume
mydict['density_calc'] = lambda x,y: density(x,y)
mydict['density'] = mydict['density_calc'](mydict['mass'],mydict['volume'])
然而,mydict ['density']是一个函数,而不是值本身。
答案 6 :(得分:0)
自引用字典几乎与您的第二次尝试(从7年前)相匹配,并且可以与使用此字典的任何其他代码很好地匹配。换句话说,它看起来仍然像鸭子一样。
mydict['mass']=2.0
print(mydict['density'])
2.0
var myImage = proxy.GetImage();
var converter = new ImageConverter();
var data = (byte[])converter.ConvertTo(myImage, typeof(byte[]);
AppDomain.Unload(tmpDomain);
pictureBox.Image = (Bitmap)converter.ConvertFrom(data);
4.0
答案 7 :(得分:-2)
这里有一个关于如何将dict
子类化以满足您的规范的快速入侵,但可能不符合Python的字典规范:
class MyDict(dict):
def __getitem__(self, key):
if key == 'density':
return self['mass'] / self['volume']
else:
return dict.__getitem__(self,key)
def keys(self):
return ['density'] + dict.keys(self)
x = MyDict()
x['mass'] = 1.0
x['volume'] = 0.5
print x
print x.keys()
print x['density']
x['mass'] = 2.0
print x['density']
打印
{'volume': 0.5, 'mass': 1.0}
['density', 'volume', 'mass']
2.0
4.0
但这并没有考虑到dict.iterkeys()等等。