I would like to understand the operation and creation of "keys" or "lambdas" that can condition the functions max()
or min()
, applied to lists, dictionaries or tuples.
An example of what I mean would be:
def pais_mas_bienes(registros, tipo_bien='Cultural'):
''' Calcula el país con mayor número de bienes de un tipo dado
Devuelve una tupla con el número de bienes y el nombre del país
ENTRADA:
- registros: lista de tuplas con información de bienes -> [(id, name, year, category, country)]
- tipo_bien: el tipo de bienes para el que se realizará la operación -> str
SALIDA:
- Tupla con el número de bienes y el nombre del país -> (int, str)
'''
tuplas = list(indexa_por_paises(registros, tipo_bien).items())
filtro = max(tuplas, key = lambda x: len(x[1]))
contador = filtra_por_pais_bienes(registros, filtro[0], tipo_bien)
result = (contador, filtro[0])
return result
And the helper functions used:
def indexa_por_paises(registros, tipo_bien):
result = {}
for i in registros:
if i[3] == tipo_bien and i[4] in result:
result[i[4]] += [i]
if i[3] == tipo_bien and i[4] not in result:
result[i[4]] = [i]
return result
def filtra_por_pais_bienes(registros, pais, tipo_bien):
result = [i for i in registros if i[3]==tipo_bien and i[4]==pais]
return len(result)
The functions
max()
andmin()
, as well as the functionsorted()
need to know how to compare two values, to determine in what order to put them and therefore which is the maximum or the minimum.By default Python already has ways to compare the basic types (integer, string, tuple, etc.). For your own types (classes) the class can incorporate a method
.__lt__()
that is evaluated to do the comparison<
, and if it is the case that the class embeds those methods,sorted()
,max()
andmin()
will use them for sorting.In case you want to override python's default rules (or those built into the class's method)
.__lt__()
, you can provide a parameter calledkey
to these functions.That parameter is the name of another function that you must program separately, or one
lambda
if the function is so simple that it merely consists of returning an expression. Whether it is a function or onelambda
, its operation is the same:Python calls your function
key
for each element of the list that it wants to sort, and sorts it according to the value returned by thekey
. It is as if it had transformed all the elements of your list into others (the ones that returnkey
), sorted those others, and then replaced each one with its original value.An example (list of tuples)
Imagine that your elements are tuples. By default python already knows how to order them and its method is to order according to the value of the first element of the tuple, and if they are equal by the second, etc. So:
But it turns out that we want it to sort by the second element . We then need to make a function that will receive each tuple and return the second element, for example like this:
Using this function like
key
:In this case the function is very simple, in other cases it could contain inside conditionals, loops or whatever you need to compute a "sort value". In cases as simple as these it may not be worth defining a function and inventing a name for it, especially if you're not going to use it anywhere else. You can use a lambda expression instead:
Moreover, for this particular case you don't even need to write the function, since it is such a common case that python already provides functions for it in its module
operator
.Here the syntax can be more confusing, because it
itemgetter(1)
is a function that, when executed, returns another function , which expects a list or tuple as a parameter, and will return its element with index 1. Personally, I find the lambda expression clearer , but it is convenient know the existence of the possibilities that it offers youoperator
for functional programming.Another example (list of dictionaries)
To compare dictionaries, python does not have a default method, so in this case it is essential to give it a
key
. The most typical case is that you want to sort the list by a particular field in the dictionary. The mechanism is similar to that seen for the tuple. For example:Or if you prefer:
Note however that all elements of the list are assumed to be dictionaries that have the key in question.
If you have particular doubts about how to define a function
key
for your particular list, ask again giving information about what the elements of the list are like and what sorting you would like for them.