sintaxis - función de python max utilizando ''clave'' y expresión lambda
lambda sintaxis (6)
Vengo de antecedentes POO y tratando de aprender Python. Estoy usando la función max
que usa una expresión lambda para devolver la instancia de tipo Player
tiene la totalScore
máxima entre los players
la lista.
def winner():
w = max(players, key=lambda p: p.totalScore)
La función devuelve correctamente la instancia del tipo Player
tiene la totalScore
máxima. Estoy confundido acerca de las siguientes tres cosas:
- ¿Cómo funciona la función
max
? ¿Cuáles son los argumentos que está tomando? Miré la documentación pero no pude entender. - ¿Cuál es el uso de la clave de palabra
key
en la función máxima? Sé que también se usa en el contexto de la función desort
- Significado de la expresión lambda? ¿Cómo leerlos? ¿Cómo trabajan?
Estas son preguntas conceptuales muy novatas pero me ayudarán a entender el lenguaje. Ayudaría si pudieras dar ejemplos para explicar. Gracias
¿Cómo funciona la función máxima?
Busca el ítem "más grande" en un iterable. Asumiré que puedes buscar lo que es, pero si no, es algo sobre lo que puedes hacer un bucle, es decir, una lista o cadena.
¿Cuál es el uso de la clave de palabra clave en la función máxima? Sé que también se usa en el contexto de la función de ordenación
Key
es una función lambda que indicará al max
qué objetos de la iterable son más grandes que otros. Diga si estaba ordenando algún objeto que creó usted mismo, y no algo obvio, como enteros.
Significado de la expresión lambda? ¿Cómo leerlos? ¿Cómo trabajan?
Esa es una pregunta más amplia. En términos simples, una lambda es una función que puede pasar , y otras piezas de código pueden usarla. Toma esto por ejemplo:
def sum(a, b, f):
return (f(a) + f(b))
Esto toma dos objetos, a
y b
, y una función f
. Llama a f()
en cada objeto, luego los suma. Así que mira esta llamada:
>>> sum(2, 2, lambda a: a * 2)
8
sum()
toma 2
y llama a la expresión lambda. Entonces f(a)
convierte en 2 * 2
, que se convierte en 4. Entonces lo hace para b
y suma los dos.
En términos no tan simples, las lambdas provienen del cálculo lambda, que es la idea de una función que devuelve una función; un concepto matemático genial para expresar el cálculo. Puedes leer sobre eso here , y luego realmente entenderlo here .
Probablemente sea mejor leer sobre esto un poco más, ya que las lambdas pueden ser confusas, y no es inmediatamente obvio lo útiles que son. Mira here .
De acuerdo con la documentation :
max (iterable [, clave])
max (arg1, arg2, * args [, clave])
Devuelve el elemento más grande en un iterable o el más grande de dos o más argumentos.Si se proporciona un argumento posicional, iterable debe ser un iterable no vacío (como una cadena no vacía, tupla o lista). Se devuelve el ítem más grande en el iterable. Si se proporcionan dos o más argumentos posicionales, se devuelve el mayor de los argumentos posicionales.
El argumento de la tecla opcional especifica una función de ordenamiento de un argumento como la utilizada para list.sort (). El argumento clave, si se proporciona, debe estar en forma de palabra clave (por ejemplo, max (a, b, c, key = func)).
Lo que esto está diciendo es que en tu caso, estás proporcionando una lista, en este caso players
. Luego, la función max
iterará sobre todos los elementos de la lista y los comparará para obtener un "máximo".
Como se puede imaginar, con un objeto complejo como un player
determinar su valor para la comparación es complicado, por lo que se le da el argumento key
para determinar cómo la función max
decidirá el valor de cada player
. En este caso, está usando una función lambda para decir "para cada p
players
obtienen p.totalscore
y lo usan como su valor para la comparación".
Versión fuertemente simplificada de max
:
def max(items, key=lambda x: x):
current = item[0]
for item in items:
if key(item) > key(current):
current = item
return current
En cuanto a lambda:
>>> ident = lambda x: x
>>> ident(3)
3
>>> ident(5)
5
>>> times_two = lambda x: 2*x
>>> times_two(2)
4
lambda
es una función anónima, es equivalente a:
def func(p):
return p.totalScore
Ahora max
convierte en:
max(players, key=func)
Pero como las sentencias def
son declaraciones compuestas, no pueden usarse donde se requiere una expresión, por eso a veces se usan lambda
.
Tenga en cuenta que lambda es equivalente a lo que pondría en una declaración de devolución de una def
. Por lo tanto, no puede usar instrucciones dentro de un lambda
, solo se permiten expresiones.
¿Qué hace el máximo?
max (a, b, c, ... [, key = func]) -> value
Con un único argumento iterable, devuelve su elemento más grande. Con dos o más argumentos, devuelve el argumento más grande.
Entonces, simplemente devuelve el objeto que es más grande.
How `key` works?
De forma predeterminada, en Python 2, la clave compara elementos en función de un conjunto de reglas basadas en el tipo de los objetos (por ejemplo, una cadena siempre es mayor que un entero).
Para modificar el objeto antes de la comparación o para comparar en función de un atributo / índice en particular, debe usar el argumento key
.
Ejemplo 1:
Un ejemplo simple, supongamos que tiene una lista de números en forma de cadena, pero desea comparar esos elementos por su valor entero.
>>> lis = [''1'',''100'',''111'',''2'']
Aquí max
compara los artículos usando sus valores originales (las cadenas se comparan lexicográficamente para que obtenga ''2''
como salida):
>>> max(lis)
''2''
Para comparar los elementos por su valor entero use la clave con un lambda
simple:
>>> max(lis, key=lambda x:int(x)) #compare `int` version of each item
''111''
Ejemplo 2: aplicar max
a una lista de listas.
>>> lis = [(1,''a''),(3,''c''), (4,''e''), (-1,''z'')]
Por defecto max will comparará los artículos por el primer índice, si el primer índice es el mismo, entonces compararía el segundo índice. Como en mi ejemplo, todos los artículos tienen un primer índice único, así que obtendría esto como la respuesta:
>>> max(lis)
(4, ''e'')
Pero, ¿y si quisieras comparar cada artículo por el valor en el índice 1? Simple, use lambda
:
>>> max(lis, key = lambda x: x[1])
(-1, ''z'')
Comparando elementos en un iterable que contiene objetos de diferente tipo :
Lista con elementos mixtos:
>>> lis = [''1'',''100'',''111'',''2'', 2, 2.57]
En Python 2 es posible comparar elementos de dos tipos diferentes :
>>> max(lis) # works in Python 2
''2''
>>> max(lis, key=lambda x: int(x)) #compare integer version of each item
''111''
Pero en Python 3 ya no puedes hacer eso :
>>> lis = [''1'',''100'',''111'',''2'', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
max(lis)
TypeError: unorderable types: int() > str()
Pero esto funciona, ya que estamos comparando la versión entera de cada objeto:
>>> max(lis, key=lambda x: int(x)) # or simply `max(lis, key=int)`
''111''
max
está construido en función que toma el primer argumento como iterable
(como lista o tupla)
La clave de argumento de palabra key
tiene su valor predeterminado None
pero acepta la función para evaluar, considere como envoltorio que evalúa iterable en función de la función
Considera este diccionario de ejemplo:
d = {''aim'':99, ''aid'': 45, ''axe'': 59, ''big'': 9, ''short'': 995, ''sin'':12, ''sword'':1, ''friend'':1000, ''artwork'':23}
Ex:
>>> max(d.keys())
''sword''
Como puede ver si solo pasa el iterable sin kwarg (una función a la key
) está devolviendo el valor máximo de la clave (alfabéticamente)
Ex. En lugar de encontrar el valor máximo de la clave alfabéticamente, es posible que deba encontrar la clave máxima por la longitud de la clave:
>>>max(d.keys(), key=lambda x: len(x))
''artwork''
en este ejemplo, la función lambda devuelve la longitud de la clave que se iterará, por lo tanto, al evaluar los valores en lugar de considerarlos alfabéticamente, hará un seguimiento de la longitud máxima de la clave y devolverá la clave que tiene la longitud máxima
Ex.
>>> max(d.keys(), key=lambda x: d[x])
''friend''
en este ejemplo, la función lambda devuelve el valor de la clave del diccionario correspondiente que tiene el valor máximo
max
función max
se usa para obtener el máximo de un iterable
.
Los iteradores pueden ser listas, tuplas, objetos dict, etc. O incluso objetos personalizados como en el ejemplo que proporcionó.
max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.
Entonces, la key=func
básicamente nos permite pasar una key
argumento opcional a la función en base a la cual se ordenan los iteradores / argumentos dados y se devuelve el máximo.
lambda
es una palabra clave de python que actúa como una pseudo función. Por lo tanto, cuando le pase el player
objeta, devolverá player.totalScore
. Por lo tanto, el iterable transferido a la función max
ordenará de acuerdo con la key
totalScore de los objetos del player
asignados y devolverá el player
que tenga la totalScore
máxima.
Si no se proporciona ningún argumento key
, el máximo se devuelve de acuerdo con los pedidos predeterminados de Python.
Ejemplos:
max(1, 3, 5, 7)
>>>7
max([1, 3, 5, 7])
>>>7
people = [(''Barack'', ''Obama''), (''Oprah'', ''Winfrey''), (''Mahatma'', ''Gandhi'')]
max(people, key=lambda x: x[1])
>>>(''Oprah'', ''Winfrey'')