Crea una funzione in Python per trovare il più alto di tutti gli argomenti delle funzioni, e restituire il “tag” del valore

StackOverflow https://stackoverflow.com/questions/4577345

  •  14-10-2019
  •  | 
  •  

Domanda

Si consideri il seguente: p1 = 1; p2 = 5; p3 = 7; più alto = max (p1, p2, p3).

La funzione di massima sarebbe tornato 7. Sto cercando di creare una funzione simile, che sarebbe tornato "P3". Ho creato una piccola funzione (da semplici confronti) per l'esempio precedente, mostrato di seguito. tuttavia Ho problemi quando il numero di argomenti salire.

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"

C'è un modo più semplice per fare questo>

È stato utile?

Soluzione

Aggiornamento: Paul Hankin ha sottolineato che max () ha preso una funzione chiave, che non conoscevo. Quindi:

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

Altre soluzioni per la completezza:

In Python 2.7 e 3.x è possibile utilizzare il dizionario comprensioni.

>>> 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'

comprensioni dizionario sono pulite. :)

Nelle versioni precedenti di Python si può fare questo:

>>> 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'

che lavorerà nel nulla dopo Python 2.2 o giù di lì.

Altri suggerimenti

Non v'è alcun modo per ottenere il nome del variabile che ha avuto il più alto valore del chiamante (perché potrebbe essere un numero o un'espressione complessa), ma utilizzando esclusivamente argomenti a parola chiave, è possibile ottenere il nome del il parametro . Qualcosa di simile a questo:

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

funziona in questo modo:

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

, ma il problema è, non funziona se uno degli argomenti è posizionale:

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

A seconda di quello che stai facendo, questo costrutto potrebbe essere più utile: (Punta di cappello a http://lemire.me/blog/archives/2008/12/17/fast-argmax-in-python/ )

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

L'unico modo per mantenere questo nulla vicino a estendibile è quello di prendere una lista come argomento e restituire l'indice del suo elemento più alto. Si può mettere un p di fronte e iniziare il conteggio a 1 se si vuole veramente.

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

Ovviamente dose non gestire argomenti di lunghezza variabile. Se si desidera che l'argomento lunghezza variabile allora questo è un problema diverso. Se si dispone di 10 argomenti poi basta aggiungerli nella definizione e restituirà il nome di argomento corretto (non necessariamente iniziare con 'p'). Ma il problema è il numero di argomenti (3 o 5 o 10 o qualsiasi altra cosa) non è variabile. Hai bisogno di sapere quanti argomenti si richiedono.

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top