Créer fonction en python pour trouver le plus élevé de tous les arguments de la fonction, et retourner le « tag » de la valeur
Question
Considérez ce qui suit: p1 = 1; p2 = 5; p3 = 7; le plus élevé = max (p1, p2, p3).
La fonction max retournerait 7. Je cherche à créer une fonction similaire, ce qui renverrait « p3 ». J'ai créé une petite fonction (par des comparaisons simples) pour l'exemple ci-dessus, illustré ci-dessous. mais je ne parviens pas à quand le nombre d'arguments augmentent.
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"
Y at-il un moyen plus simple de le faire>
La solution
Mise à jour: Paul Hankin a souligné que max () a pris une fonction clé, que je ne connaissais pas. Donc:
>>> def argmax(**kw):
... return max(kw, key=kw.get)
...
>>> argmax(foo=3, bar=5, frotz=1, kaka=-3)
'bar'
D'autres solutions pour l'exhaustivité:
En Python 2.7 et 3.x, vous pouvez utiliser le dictionnaire compréhensions.
>>> 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'
Dictionnaire compréhensions sont propres. :)
Dans les versions antérieures de Python que vous pouvez faire ceci:
>>> 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'
Ce qui va travailler dans quoi que ce soit après Python 2.2 ou plus.
Autres conseils
Il n'y a pas moyen d'obtenir le nom de variable qui avait la valeur la plus élevée dans le appelant (car il peut être un nombre ou une expression complexe), mais en utilisant des arguments clés exclusivement, vous pouvez obtenir le nom du paramètre . Quelque chose comme ceci:
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
fonctionne comme ceci:
>>> argmax(a=1,b=2,c=3)
'c'
mais la prise est, il ne fonctionne pas si l'un des arguments est de position:
>>> argmax(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argmax() takes exactly 0 arguments (3 given)
En fonction de ce que vous faites, cette construction pourrait être plus utile: (pointe chapeau http://lemire.me/blog/archives/2008/12/17/fast-argmax-in-python/ )
>>> a = [9,99,999]
>>> a.index(max(a))
2
La seule façon de garder ce tout près extensible est de prendre une liste comme argument et renvoie l'index de son élément le plus élevé. Vous pouvez mettre un p à l'avant et commencer à compter à 1 si vous voulez vraiment.
def highest(x):
return 'p' + repr(x.index(max(x))+1)
De toute évidence, il dose gère pas les arguments de longueur variable. Si vous voulez l'argument de longueur variable alors c'est une autre question. Si vous avez 10 arguments alors il suffit de les ajouter dans la définition et renverra le nom de l'argument correct (pas nécessairement commencé par « p »). Mais le hic est le nombre d'arguments (3 ou 5 ou 10 ou tout autre chose) ne soit pas variable. Vous devez savoir combien d'arguments dont vous avez besoin.
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)