Listas por Comprensión en Python

Las listas por comprensión proporcionan una forma muy sencilla de crear listas a partir de secuencias (list/listas, tuple/tuplas, dict/diccionarios, set/conjuntos, str/cadenas). El uso más común de esta característica es el de construir listas, donde cada uno de sus elementos son el resultado de alguna operación aplicada a cada uno de los elementos de la secuencia, o para crear una sub-secuencia de elementos que cumplan ciertas condiciones.

Las listas por comprensión están compuestas por corchetes, los cuales encierran una expresión seguida por una cláusula for y, a continuación cero o más cláusulas for o cláusulas if.

Aquí tomamos una lista de números y retornamos una lista con sus cubos

>>> numeros = range(1, 5)     # Equivalente a 'numeros = [1, 2, 3, 4]'
>>> [x**3 for x in numeros]
[1, 8, 27, 64]

Podemos realizar operaciones tales como convertir una tupla de cadenas a una lista de enteros:

>>> cadenas = ("23", "2", "465")
>>> [int(x) for x in cadenas]
[23, 2, 465]

Lee el resto de esta entrada »

Anuncios

Sobrecarga de operadores en Python

En la Programación Orientada a Objetos (OOP por sus siglas en ingles), la sobrecarga se refiere a la posibilidad de contar con dos o mas funciones con el mismo nombre pero con comportamiento diferentes. La sobrecarga de operadores trata básicamente de lo mismo, solo que en el ámbito de los operadores (+, , *, /, etc).

¿Cuál es la ventaja de contar con esta característica? Para responder esta pregunta deseo mostrarles el siguiente código Java

/*
 * Supongamos que la clase Matriz existe y que su constructor genera un arreglo
 * bidimensional de enteros, relleno de ceros, es decir, para toda celda de la
 * matriz, matriz[i][j] == 0
 */

Matriz mi_matriz = Matriz(10, 20);
Matriz otra_matriz = Matriz(10, 20);

/*
 * Para sumar nuestras matrices, tendríamos que invocar al método del objeto
 * de tipo Matriz llamado Sumar
 */
Matriz matriz_suma = mi_matriz.Sumar(otra_matriz);

Todo bien, pero ¿Y si pudiéramos utilizar el símbolo suma (+) para realizar la última línea del código anterior? ¿No sería eso genial? Pues, de eso se trata la sobrecarga de operadores y ahora les mostraré como hacerlo en Python.

Lee el resto de esta entrada »

Crear un menú en python (no GUI)

En esta ocasión deseo compartir una forma (muy personal) de realizar menús en Python. Tal y como se puede ver en el título, no me refiero a un menú gráfico sino a uno muy tradicional, de línea de comandos. Debo aclarar que el menú que verán a continuación puede ser implementado sin la utilización de una clase, sin embargo, este enfoque brinda la ventaja de contar con código bien organizado, fácil de leer, depurar y modificar.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# menu.py

#----------------------------------------------------------------------- Módulos
import os
import sys

#-------------------------------------------------------------------- Constantes
LIMPIAR = "clear" if sys.platform.startswith("linux") else "cls"

#------------------------------------------------------------------------ Clases
class Menu(object) :
    """Lista de funciones opcionales, las cuales le permitirán al usuario
    realizar operaciones matemáticas básicas.

    Argumentos
        prompt -- Es el prompt del menú (default '>')
    """

    def __init__(self, prompt=">") :
        self.prompt = prompt + " "
        self.opciones = [
            self.opcion_sumar,
            self.opcion_restar,
            self.opcion_multiplicar,
            self.opcion_dividir,
            self.opcion_salir,
        ]
        self.presentacion = "------------------ Bienvenido ------------------\n"

        for numero, opcion in enumerate(self.opciones, 1) :
            self.presentacion += "{0}. {1}\n".format(numero, opcion.__name__[7:])

    def loop(self) :
        while True:
            print self.presentacion

            try:
                seleccion = int(raw_input(self.prompt))

                if seleccion >= 1 and seleccion < len(self.opciones) :
                    op1, op2 = self.pedir_operandos()
                    # Los indices van desde 0 hasta len(self.opciones)-1
                    resultado = self.opciones[seleccion - 1](op1, op2)
                    raw_input("\nEl resultado es {0}".format(resultado))

                # Caso especial para la opción "salir"
                elif seleccion == len(self.opciones) :
                    self.opciones[seleccion - 1]()

                else:
                    raw_input("Error: Opción invalida")

            except ValueError:
                raw_input("Error: Debes introducir un número")

            except ZeroDivisionError:
                raw_input("Acaso quieres destruir el universo!?")

            except KeyboardInterrupt:
                break

            os.system(LIMPIAR)

    def pedir_operandos(self) :
        while True:
            print "Por favor, ingrese el primer operando"

            try:
                op1 = int(raw_input(self.prompt))
            except ValueError:
                print "Error: Debes introducir un número\n"
            else:
                break

        while True:
            print "Por favor, ingrese el segundo operando"

            try:
                op2 = int(raw_input(self.prompt))
            except ValueError:
                print "Error: Debes introducir un número\n"
            else:
                break

        return op1, op2

    def opcion_sumar(self, op1, op2) :
        return op1 + op2

    def opcion_restar(self, op1, op2) :
        return op1 - op2

    def opcion_multiplicar(self, op1, op2) :
        return op1 * op2

    def opcion_dividir(self, op1, op2) :
        return op1 / op2

    def opcion_salir(self) :
        # Aquí podría ir un mensaje de despedida
        raise KeyboardInterrupt()

Para poder ver nuestro menú andando solo necesitamos importarlo en el script (archivo python o incluso el interprete interactivo) en el cual será utilizado

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# main.py

import menu

mi_menu = menu.Menu()
mi_menu.loop()

Y listo. Espero que les haya sido de ayuda 😉

Crear matrices en python utilizando listas

A diferencia de lenguajes como C, en Python no resulta intuitivo el proceso de creación de una matriz. Este post está escrito con el objetivo de brindar una solución a este problema a través de la utilización de listas. A continuación, pongo a su disposición fragmentos de código que yo mismo he escrito y utilizado a la hora de implementar una matriz en mis scripts.

# La mas sencilla e intuitiva
matriz = []
for i in range(numero_filas):
    matriz.append([])
    for j in range(numero_columnas):
        matriz[i].append(None)

# Menos intuitiva pero mas eficiente
matriz = [None] * numero_filas
for i in range(numero_filas):
    matriz[i] = [None] * numero_columnas

# Mal
matriz = [[None] * numero_columnas] * numero_filas

# Versión mas compacta
matriz = [range(numero_columnas) for i in range(numero_filas)]

# Variación de la anterior
matriz = [[None] * numero_columnas for i in range(numero_filas)]

El recetario para mostrar matrices lo debo para una próxima entrega del blog 😉

Nota del pie:

La razón por la cual el código de la línea 14 esta mal es muy fácil de entender, Python evalúa una y solo una vez la expresión que posteriormente sera copiada y concatenada numero_filas-veces, es decir, la expresión

[[None] * numero_columnas]

siempre hará referencia a la misma lista y en consecuencia al escribir

matriz[i][j] = valor

estaremos modificando mas de una celda a la vez (porque dichas celdas harán referencia al mismo objeto).

Publicado en Recetas. Etiquetas: , , . Leave a Comment »