sábado, 11 de junio de 2011

Listas por comprensión

Yo pensaba que las facilidades para trabajar con vectorización, seleccionando en una sola instrucción todos aquellos elementos de un vector o lista que satisfacen cierto criterio, era algo exclusivo a R que no existía en Python. Como novato de Python, estaba muy equivocado - Python no deja de sorprender ...

La trahison des images (ceci n'est pas une pipe) - 1928/1929
René Magritte

Resulta que eso en Python se llama "listas por comprensión" y la sintaxis de este tipo de expresiones es muy parecida a la notación de conjuntos matemática (definición de conjuntos por comprensión), de modo que es muy intuitivo.  Nos referimos pues a dicha notación identificando algunos de sus elementos:

  • Función de salida: son expresiones que involucran a la variable x y que vienen a ser los elementos que constituyen el nuevo conjunto (o lista) a definir.
  • Variable: es una variable dummy que figura en toda la expresión.
  • Conjunto de entrada: es el conjunto (la lista) a partir de la cual se toman los elementos x.
  • Predicado: es una condición lógica que deben verificar los elementos x para que, aplicándoles f(x), formen parte del nuevo conjunto 8la nueva lista)
En python, la función de salida se representa mediante una expresión, la expresión "x pertenece a A" se indica mediante un constructo Python (for x in A) y el predicado es un constructo Python con if: if p(x), donde p(x) es una expresión que genera un booleano.  Así por ejemplo, si a partir de una con todos los numeros naturales entre 1 y 5, quisieramos generar una nueva lista con cada número de esos elevado al cuadrado, la expresión matemática y la correspondiente expresión en python serían:

A=range(1,6)
[x**2 for x in A]

lo cual arrojaría la siguiente lista en la consola de comandos de Python:

[1, 4, 9, 16, 25]

Nótese que se ha omitido la clausula if (el predicado), aunque esta expresión sería totalmente equivalente a la anterior:

[x**2 for x in A if 1<=x<=5]

Otro ejemplo, supóngase que A es el conjunto de todos los números enteros entre -20 y 20.  ¿Cuales de entre esos números son tales que elevados al cuadrado, están entre 50 y 90?


A=range(-20,21)
[x for x in A if 50<=x**2<=100]

lo cual genera:
 [-8, -9, 8, 9]


Python no es el único lenguaje con listas por comprensión.  Otros lenguajes funcionales como Haskell también incluyen este tipo de constructos.

No hay comentarios:

Publicar un comentario