Mostrando entradas con la etiqueta listas por comprensión. Mostrar todas las entradas
Mostrando entradas con la etiqueta listas por comprensión. Mostrar todas las entradas

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.