Bienvenidos sean a este post, hoy nos centraremos en hablar sobre la funcion map, la definicion de la funcion es:
Devuelve un iterador que aplica la funcion a cada elemento del iterable y conteniendo los resultados, si se pasan mas argumentos iterables, la funcion debe tomar esa cantidad de iterables y se aplica a todos los elementos de los iterables en paralelo y este se detiene cuando el iterable mas corto finaliza
Guido van Rossum
Para entender el concepto vamos a ver una serie de ejemplos, pero antes veamos su sintaxis:
map(funcion, iterador)
Como pueden observar primero ira la funcion y luego el iterador, pasemos con el primero:
>>> map(lambda *a: a, range(3))
<map object at 0x7f9e30e36ac8>
>>>
Para esta serie de ejemplos en lugar de usar una funcion utilizaremos a lambda, del cual hablamos en este post, para no tener que generar una funcion nueva por cada uno, en este caso como elemento iterador usamos a range pero como observamos nos devolvio una respuesta que no nos sirve, para solucionar esto vamos a utilizar un alias para list y luego modificaremos el ejemplo anterior, veamos el ejemplo:
>>> _ = list
>>> _(map(lambda *a: a, range(3)))
[(0,), (1,), (2,)]
>>>
Ahora si obtuvimos un listado, en ella podemos ver como trabaja map con un objeto iterable, probemos con dos objetos iterables:
>>> _(map(lambda *a: a, range(3), 'abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]
>>>
Podemos ver como se relacionaron los dos objetos iterables que informamos, vamos a probar con tres objetos iterables:
>>> _(map(lambda *a: a, range(3), 'abc', range(4, 7)))
[(0, 'a', 4), (1, 'b', 5), (2, 'c', 6)]
>>>
Como pueden observar a medida que agreguemos mas elementos iterables se iran asociando por cada uno de ellos, ahora vamos a probar con el concepto del iterador mas corto, veamos el primer ejemplo:
>>> _(map(lambda *a: a, (), 'abc'))
[]
>>>
En este caso nos devolvio el mapa vacio porque informamos un tuple vacio, veamos el siguiente caso:
>>> _(map(lambda *a: a, (1,2), 'abc'))
[(1, 'a'), (2, 'b')]
>>>
En este ejemplo vemos como al llegar al final del primer elemento iterador se detuvo la carga de elementos en el map y esto aplica a todos los elementos iterables que informemos, como podemos ver es una herramienta muy util cuando debemos aplicar una misma funcion para una o mas colecciones, a continuacion veremos una herramienta que fue muy popular al comienzo de python pero cuando aparecio la opcion de clave-funciones esta comenzo a usarse cada vez menos, se lo conoce como idioma decora-ordena-sin decorar o tambien como Tranformacion Schwartzian.
Para entender este concepto vamos a utilizar un ejemplo donde queremos ordenar en forma descendente la suma de las notas acumuladas por los estudiantes, por lo tanto el mejor estudiante estara en la posicion 0, debemos escribir una funcion para producir el objeto decorado, lo ordenamos para luego desordenarlo o quitamos la decoracion, cada estudiante tiene notas en tres diferentes asignaturas, dentro de este contexto decorar un objeto significa transformarlo, ya sea agregando informacion adicional o poniendolo en otro objeto, en una forma que nos permita ordenar los objetos originales de la forma que queramos, si bien esto no tiene nada que ver con los decoradores de python de los cuales hablaremos mucho mas adelante, por ultimo cuando hablamos de sin decorar o desordenar nos referimos a la capacidad de volver los datos a su posicion original antes de ordenarlos, para entender como trabaja esta transformacion veamos el siguiente ejemplo, para ello primero crearemos un archivo llamado estudiantes.py y luego agregaremos el siguiente codigo:
estudiantes.py
estudiantes = [
dict(id=0, notas=dict(matematica=9,fisica=6,historia=7)),
dict(id=1, notas=dict(matematica=6,fisica=7,latin=10)),
dict(id=2, notas=dict(historia=8,fisica=9,quimica=10)),
dict(id=3, notas=dict(matematica=5,fisica=5,geografia=7)),
]
def decorar(estudiante) :
return (sum(estudiante['notas'].values()), estudiante)
def sin_decorar(estudiante_decorado) :
return estudiante_decorado[1]
def mostrar(a) :
for valor in a:
print(valor)
estudiantes=sorted(map(decorar, estudiantes), reverse=True)
estudiantes=list(map(sin_decorar, estudiantes))
mostrar(estudiantes)
Primero vamos a crear un diccionario llamado estudiantes donde guardaremos a cuatro estudiantes con sus respectivas notas, y cada uno tendra su respectivo id, lo siguiente sera la funcion decorar que recibira al estudiante y devolvera la suma de todas sus notas seguido de la informacion del mismo, la siguiente es una funcion que devolvera solamente los datos del estudiante «decorado», por ultimo tenemos una funcion llamada mostrar para ver los datos finales, lo siguiente sera ordenar a estudiantes para ello usamos a sorted, luego a map, le pasamos la funcion decorar y a estudiantes, por ultimo establecemos a reverse como True para ordenarlo de mayor a menor, como usamos decorar ahora tenemos el primer campo que sera usado para ordenarlo, veamos como se ve a estudiantes decorado:
(22, {'id': 0, 'notas': {'matematica': 9, 'fisica': 6, 'historia': 7}})
Observen como ahora tenemos primero la suma de todas sus notas, seguido de todos los datos del alumno o estudiante, ahora estudiantes esta ordenado pero se ve la suma de las notas y nosotros no queremos que se vean y aca entra en accion sin_decorar, usamos a map nuevamente pero usaremos la funcion sin_decorar y pasamos a estudiantes, en este caso como la funcion solo muestra los datos del alumno hace desaparecer la nota, es decir eliminamos la decoracion, por lo tanto ahora tenemos una version ordenada pero sin ver como se ordenaron, por ultimo usamos mostrar para ver el resultado final, ejecutemos y veamos como quedo:
tinchicus@dbn001vrt:~/python$ python3 estudiantes.py
{'id': 2, 'notas': {'historia': 8, 'fisica': 9, 'quimica': 10}}
{'id': 1, 'notas': {'matematica': 6, 'fisica': 7, 'latin': 10}}
{'id': 0, 'notas': {'matematica': 9, 'fisica': 6, 'historia': 7}}
{'id': 3, 'notas': {'matematica': 5, 'fisica': 5, 'geografia': 7}}
tinchicus@dbn001vrt:~/python$
Observen como quedo ordenado el listado y dando la sensacion de que el codigo lo ordeno en base a la informacion almacenada para cada estudiante pero en realidad lo que hicimos fue «decorar» con la suma de todas las notas, ordenarlas en base a ese dato para finalmente quitar la decoracion y mostrar la informacion como si nada hubiera ocurrido pero con los datos ordenados.
En resumen, hoy hemos visto la funcion map, su sintaxis, como trabaja, en que nos puede ayudar, tambien vimos una forma de trabajo muy particular donde podemos generar un orden en base a tres formas de procesar la informacion pero que al dia de hoy ha quedado obsoleto, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.00
