如何找到最小(或最大)属性的名称?

时间:2019-07-19 19:31:17

标签: 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'?

3 个答案:

答案 0 :(得分:2)

您无法获得像这样的最小值/最大值的变量名称 * ,因为正如@jasonharper所评论的那样:cab仅不过是包含三个整数的列表;绝对与这些整数最初来自的变量没有任何联系。

一个简单的解决方法是对用户 pairs ,如下所示:

>>> pairs = [("a", 12), ("b", 9), ("c", 42)]
>>> min(pairs)
('b', 9)
>>> min(pairs)[0]
'b'

请参阅Green Cloak Guy的答案,但是如果您想提高可读性,我建议采用类似的方法。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

要使此方法有效,您必须具有很大的创造力,而我能想到的唯一解决方案是效率很低。

您可以很容易地获得指向数据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]

此解决方案有两个大问题:

  1. 命名空间-您不能将此代码放入函数中,因为如果您这样做然后从另一个函数中调用它,则它将无法正常工作。
  2. 时间-这需要搜索整个全局名称空间。

第一个问题可以通过将当前名称空间另外作为变量传递来缓解:

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'