Python 如何查找最小(或最大)属性的名称?
给定三个或三个以上的变量,我想找到具有最小值的变量的名称 我可以从列表中得到最小值,我可以得到最小值列表中的索引。但是我想要变量名 我觉得有另一种方法可以解决这个问题,我只是没有想到Python 如何查找最小(或最大)属性的名称?,python,list,Python,List,给定三个或三个以上的变量,我想找到具有最小值的变量的名称 我可以从列表中得到最小值,我可以得到最小值列表中的索引。但是我想要变量名 我觉得有另一种方法可以解决这个问题,我只是没有想到 a = 12 b = 9 c = 42 cab = [c,a,b] # yields 9 (the min value) min(cab) # yields 2 (the index of the min value) cab.index(min(cab)) 什么代码会产生“b”?您无法获得具有如下*的最小
a = 12
b = 9
c = 42
cab = [c,a,b]
# yields 9 (the min value)
min(cab)
# yields 2 (the index of the min value)
cab.index(min(cab))
什么代码会产生“b”?您无法获得具有如下*的最小/最大值的变量名称,因为@jasonharper评论道:cab只不过是一个包含三个整数的列表;与这些整数最初来自的变量完全没有联系
一个简单的解决方法是创建用户对,如下所示:
>>> pairs = [("a", 12), ("b", 9), ("c", 42)]
>>> min(pairs)
('b', 9)
>>> min(pairs)[0]
'b'
请看Green Clope Guy的答案,但如果您想提高可读性,我建议您采用与我类似的方法。您无法获得具有最小/最大值的变量名,例如*,因为正如@jasonharper所评论的:cab只不过是一个包含三个整数的列表;与这些整数最初来自的变量完全没有联系
一个简单的解决方法是创建用户对,如下所示:
>>> pairs = [("a", 12), ("b", 9), ("c", 42)]
>>> min(pairs)
('b', 9)
>>> min(pairs)[0]
'b'
请看Green Clope Guy的答案,但如果您想提高可读性,我建议您采用与我类似的方法。您必须非常有创意才能使其发挥作用,而我能想到的唯一解决方案是相当低效的 您可以相当容易地获得b引用的数据的内存地址:
>>> hex(id(b))
'0xaadd60'
>>> hex(id(cab[2]))
'0xaadd60'
但是,要将其与变量名对应起来,唯一的方法是查看变量并找到指向正确位置的变量
可以使用globals函数执行此操作:
# get a list of all the variable names in the current namespace that reference your desired value
referent_vars = [k for k,v in globals().items() if id(v) == id(cab[2])]
var_name = referent_vars[0]
此解决方案存在两大问题:
名称空间-您不能将此代码放入函数中,因为如果您这样做,然后从另一个函数调用它,那么它将无法工作。
时间-这需要搜索整个全局命名空间。
第一个问题可以通过另外将当前名称空间作为变量传入来缓解:
def get_referent_vars(val, globals):
return [k for k,v in globals.items() if id(v) == id(val)]
def main():
a = 12
b = 9
c = 42
cab = [a, b, c]
var_name = get_referent_vars(
cab[cab.index(min(cab))],
globals()
)[0]
print(var_name)
# should print 'b'
你必须非常有创意才能让它发挥作用,而我能想到的唯一解决方案是相当低效的 您可以相当容易地获得b引用的数据的内存地址:
>>> hex(id(b))
'0xaadd60'
>>> hex(id(cab[2]))
'0xaadd60'
但是,要将其与变量名对应起来,唯一的方法是查看变量并找到指向正确位置的变量
可以使用globals函数执行此操作:
# get a list of all the variable names in the current namespace that reference your desired value
referent_vars = [k for k,v in globals().items() if id(v) == id(cab[2])]
var_name = referent_vars[0]
此解决方案存在两大问题:
名称空间-您不能将此代码放入函数中,因为如果您这样做,然后从另一个函数调用它,那么它将无法工作。
时间-这需要搜索整个全局命名空间。
第一个问题可以通过另外将当前名称空间作为变量传入来缓解:
def get_referent_vars(val, globals):
return [k for k,v in globals.items() if id(v) == id(val)]
def main():
a = 12
b = 9
c = 42
cab = [a, b, c]
var_name = get_referent_vars(
cab[cab.index(min(cab))],
globals()
)[0]
print(var_name)
# should print 'b'
如果您想在实例变量中包含内容,vars的魔力可以防止您必须预先编写字典:
class Foo():
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def min_name(self, names = None):
d = vars(self)
if not names:
names = d.keys()
key_min = min(names, key = (lambda k: d[k]))
return key_min
行动中
>>> x = Foo(1,2,3)
>>> x.min_name()
'a'
>>> x.min_name(['b','c'])
'b'
>>> x = Foo(5,1,10)
>>> x.min_name()
'b'
现在,如果在min_name的参数列表中传递无效的变量名,它将崩溃,但这是可以解决的
您还可以更新字典,它会反映在源代码中
def increment_min(self):
key = self.min_name()
vars(self)[key] += 1
例如:
>>> x = Foo(2,3,4)
>>> x.increment_min()
>>> x.a
3
如果您想在实例变量中包含内容,vars的魔力可以防止您必须预先编写字典:
class Foo():
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def min_name(self, names = None):
d = vars(self)
if not names:
names = d.keys()
key_min = min(names, key = (lambda k: d[k]))
return key_min
行动中
>>> x = Foo(1,2,3)
>>> x.min_name()
'a'
>>> x.min_name(['b','c'])
'b'
>>> x = Foo(5,1,10)
>>> x.min_name()
'b'
现在,如果在min_name的参数列表中传递无效的变量名,它将崩溃,但这是可以解决的
您还可以更新字典,它会反映在源代码中
def increment_min(self):
key = self.min_name()
vars(self)[key] += 1
例如:
>>> x = Foo(2,3,4)
>>> x.increment_min()
>>> x.a
3
没有任何东西会产生“b”。cab只不过是一个包含三个整数的列表;与那些整数最初来自的变量完全没有联系。我过度简化了。a、 b和c实际上是类属性的代理。我想找出哪个属性的值最低。我不太关心最小值是9,而更多的是object.b小于object.a和object.c。所以如果这些是角色属性,我希望能够找到哪个属性是最弱的,并增加该属性,不管它是什么;[foo.c,foo.a,foo.b]也只是一个值列表,没有关于值来自何处的内存。没有任何东西会产生“b”。cab只不过是一个包含三个整数的列表;与那些整数最初来自的变量完全没有联系。我过度简化了。a、 b和c实际上是类属性的代理。我想找出哪个属性的值最低。我不太关心最小值是9,而更多的是object.b小于object.a和object.c。所以如果这些是角色属性,我希望能够找到哪个属性是最弱的,并增加该属性,不管它是什么;[foo.c,foo.a,foo.b]也只是一个值列表,没有关于这些值来自何处的内存。那么,这是可行的,很好!在架子上试过
它在那里工作!值得注意的是,只有当变量保持不变时,这才有效。如果在任何时候您对它们进行赋值并覆盖名称空间中的名称,则它将停止工作。它几乎是python中唯一不可变的东西,但内存是不可变的,所以请记住,你永远不能更改b或cab[2],否则它会崩溃。是的,这是有道理的,我同意。这是非常棒的信息,而且肯定能理解我的实际要求。我想gsamaras的回答更符合我的本意。我可以使用一个简单的字典来了解哪个属性包含最小值。谢谢你们!!还有一种更像蟒蛇的方式。。。看看我上面的答案。那就可行了,很好!在一个壳里试过-它在那里有效!值得注意的是,只有当变量保持不变时,这才有效。如果在任何时候您对它们进行赋值并覆盖名称空间中的名称,则它将停止工作。它几乎是python中唯一不可变的东西,但内存是不可变的,所以请记住,你永远不能更改b或cab[2],否则它会崩溃。是的,这是有道理的,我同意。这是非常棒的信息,而且肯定能理解我的实际要求。我想gsamaras的回答更符合我的本意。我可以使用一个简单的字典来了解哪个属性包含最小值。谢谢你们!!还有一种更像蟒蛇的方式。。。看我上面的答案。哦,那更好。谢谢哦,那更好。谢谢