在python中创建函数以查找所有函数参数中的最高者,并返回值的“标记”

时间:2011-01-02 05:58:31

标签: python function highest

请考虑以下事项: P1 = 1; P2 = 5; P3 = 7; 最高= MAX(P1,P2,P3)。

max函数将返回7.我正在寻找创建一个类似的函数,它将返回“p3”。我为上面的例子创建了一个小函数(通过简单的比较),如下所示。但是当争论的数量增加时,我遇到了麻烦。

def highest(p1,p2,p3):
    if (p1>p2) and (p1>p3):
        return "p1"
    if (p2>p1) and (p2>p3):
        return "p2"
    if (p3>p1) and (p3>p1):
        return "p3"

有更简单的方法吗?

4 个答案:

答案 0 :(得分:5)

无法获取调用者中具有最高值的变量的名称(因为它可能是数字或复杂表达式),但是通过使用关键字参数,您可以获取参数的名称。像这样:

def argmax(**kwargs):
    mx = -1e+400 # overflows to -Inf
    amx = None
    for k, v in kwargs.iteritems():
        if v > mx:
            mx = v
            amx = k
    return amx

像这样工作:

>>> argmax(a=1,b=2,c=3)
'c'

但问题是,如果任何参数是位置的,它就不起作用:

>>> argmax(1,2,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argmax() takes exactly 0 arguments (3 given)

根据你正在做的事情,这个结构可能更有用:(帽子提示http://lemire.me/blog/archives/2008/12/17/fast-argmax-in-python/

>>> a = [9,99,999]
>>> a.index(max(a))
2

答案 1 :(得分:5)

更新:Paul Hankin指出max()采用了一个关键功能,我不知道。所以:

>>> def argmax(**kw):
...   return max(kw, key=kw.get)
... 
>>> argmax(foo=3, bar=5, frotz=1, kaka=-3)
'bar'

完整性的其他解决方案:

在Python 2.7和3.x中,您可以使用字典理解。

>>> def argmax(**kw):
...     wk = {v:k for k,v in kw.items()}
...     return wk[max(wk)]
... 
>>> argmax(foo=3, bar=5, frotz=1, kaka=-3)   
'bar'

字典理解很整洁。 :)

在早期版本的Python中,您可以这样做:

>>> def argmax(**kw):
...     wk = dict([(v,k) for k,v in kw.items()])
...     return wk[max(wk)]
... 
>>> argmax(foo=3, bar=5, frotz=1, kaka=-3)   
'bar'

在Python 2.2之后的任何内容都可以使用。

答案 2 :(得分:0)

显然,它不会处理可变长度的参数。如果你想要可变长度参数,那么这是一个不同的问题。如果你有10个参数,那么只需在定义中添加它们,它将返回正确的参数名称(不一定以'p'开头)。但是捕获的是参数的数量(3或5或10或其他任何东西)不可变。你需要知道你需要多少个参数。

def highest(p1,p2,p3,p4,p5):
    d = locals()
    keys = d.keys()
    max_key = keys[0]
    max_val = d[max_key]
    for i in range(1,len(keys)):
        key = keys[i]
        val = d[key]
        if val > max_val:
            max_val = val
            max_key = key

    return max_key

print highest(3,2,5,10,1)
print highest(1,5,2,2,3)
print highest(5,2,5,1,11)
print highest(3,2,1,1,2)

答案 3 :(得分:0)

保持这一点接近可扩展性的唯一方法是将列表作为参数并返回其最高元素的索引。如果你真的想要,你可以在前面放一个p并从1开始计数。

def highest(x):
    return 'p' + repr(x.index(max(x))+1)