Python es un lenguaje de programación procedural con una sintaxis muy limpia y bonita. Además tiene una gran cantidad de recursos que lo han convertido en uno de los lenguajes de programación predilecto entre programadores. A continuación presentaremos algunas de sus características esenciales.
Tipos
Python cuenta con los tipos básicos comunes en otros lenguajes: boleanos, enteros, flotantes y cadenas:
True
False
1
2
1.3
0.34
"hola"
"mundo"
En Python las variables no son tipificadas, son más bien contenedores y uno puede re-asignarle cualquier tipo de valor en ellas:
variable=5
variable+1
variable="hola"
variable+" mundo"
Python cuenta con varias estructuras de datos a nuestra disposición. Las más comunes son: listas, tuplas y diccionarios.
[1,2,3]
(1,2,3)
{"hola":1,"mundo":2,"!",3}
Listas
Las listas son una estructura “mutable”, esto quiere decir que pueden cambiar durante la ejecución del código. Para hacer esto tienen asociadas a ellas varias funciones:
lista=[1,2,3]
lista.append(4)
lista.append(5)
print lista
lista.pop()
print lista
print len(lista)
Las lista en Python pueden ser visualizados como arreglos y podemos acceder a sus elementos a través de índices. La interfaz de la lista acepta indices negativos y rangos.
print lista[0]
print lista[-1]
print lista[1:2]
print list2[:1]
print lista[-2:]
lista[1]=20
print lista
Las listas también son contenedores y el contenido de ésta puede ser de cualquier tipo.
lista=["hola",1,"mundo"]
print lista
lista.append(True)
print lista
Tuplas
Las tuplas a diferencias de las listas son inmutables. Una vez definidos no es posible cambiar sus valores o su contenido. Las tuplas también tienen una interfaz de acceso similares a las listas.
tupla=(1,2,3)
print tupla[0]
print tupla[-1]
print tupla[1:2]
print tupla[:2]
print tupla[-2:]
print len(tupla)
Diccionarios
Los diccionarios son una estructura que permite el acceso de un valor a través de una llave. Por lo anterior, para construirlos les tenemos que pasar ambos: llaves y valores. En este caso la única restricción es que la llave sea un tipo ‘hasheable’, que son todos los tipos básicos.
diccionario={'hola':3,'mundo':2,'!':1}
print diccionario
print diccionario['mundo']
print diccionario.keys()
print diccionario.values()
print diccionario.items()
Los valores de estas estructuras no están limitadas a valores básicos y podemos hacer cosas como las siguientes:
rara=[({'hola':1,"mundo":2},"hola mundo"),["hola","mundo"]]
Programas en Python
Un programa en Python es una secuencia de instrucciones en un archivo de texto; y generalmente nos gusta ponerles la extensión .py para identificarlos.
Para ejecutarlos, lo hacemos de la siguiente forma:
python miprograma.py
Para marcar el final de la instrucción en nuestro programa usamos un enter.
Bloques de código se marcan a través de identación: instrucciones con la misma
identación pertenecen al mismo bloque. NOTA Hay que tener cuidado entre
TABs y espacios, aunque en la pantalla se vean con la misma identación,
TABS y espacios son considerados diferentes bloques.
El inicio de un bloque se marca con : en la línea anterior al comienzo del bloque. Un programa en Python generalmente luce de la siguiente forma con respecto a la identación:
instruccion1
instruccion2
instruccion_de_control:
instruccion_bloque_1
instruccion_bloque_2
instruccion_de_control:
instruccion_bloque_3
instruccion_bloque_4
instruccion_de_control:
instruccion_de_control:
instruccion_bloque_5
instruccion_bloque_6
instruccion_bloque_7
instruccion_bloque_8
Control
Hay tres formas de control muy usadas en programas de Python: if, for y while.
if
Ifs en python son muy directos, es la palabra reservada if seguida una expresión que se evalué a un valor de verdad:
if variable>0:
print "Este valor fue mayor que cero"
Es posible asociar al if un caso contrario a través de la palabra reservada else:
if variable == 0:
print "Este valor es igual a cero"
else:
print "Este valor no es igual a cero"
Y para hacer if consecutivos exclusivos (construcción case) podemos usar if y la palabra reservada elif
if variable == 0:
print "Este valor es igual a cero"
elif variable==1:
print "Este valor no es igual a uno"
elif variable==2:
print "Este valor no es igual a dos"
else:
print "Este valor no es cero, uno o dos"
for
Una opción para hacer repeticiones de código es usar for. El for itera sobre una lista o objeto iterable y extrae los valores para usarlo en el bloque de código que le sigue:
lista=['hola','mundo']
for w in lista:
print "Este es un elemento de la lista",w
Esto es diferente a otros lenguajes, donde se usa un contador. Para lograr un efecto similar, se puede crear una lista con la ayuda de la función range con el objetivo de contar de la siguiente forma:
lista=range(10)
print lista
for i in lista:
print "Contando...",i
Tuplas son iterativas:
tupla=(1,2,3)
print "Iterando una tupla",tupla
for i in tupla:
print i
Los diccionarios de manera directa no son iterativos, pero es posible llamar un iterador (función iteritems)sobre ellos:
diccionario={"hola":1,"mundo":2}
print "Iterando el diccionario directamente",diccionario
for k,v in diccionario.itermitems():
print "Llave:",i
print "Valor:",v
Pero es posible iterar la lista de elementos de un diccionario, la diferencia es que se crea una lista temporal para lograr la iteración (función items).
print "Iterando la listas de lementos de un diccionario",diccionario
for k,v in diccionario.items():
print "Llave:",i
print "Valor:",v
while
Los whiles son muy similares a otros lenguajes:
i=0
while i<10:
print "Contanndo con while...",i
i+=1
Además del control normal, Python ofrece la palabra reservada break para romper ciclos (fors y whiles):
i=0
while True:
print "Contanndo con while...",i
if i==10:
break
i+=1
Y también podemos hacer ciclos infinitos:
while True:
pass #Esta instrucción no hace nada
Módulos
Gran parte del éxito de Python es que viene con pilas incluidas… éstas son una cantidad de módulos que podemos incorporar en nuestro código.
Para cargarlos usamos la palabra reservada import. Módulos importados de esta forma conservan el ‘namespace’ del módulo, por lo que para usar una de las funciones del módulo tenemos que hacer referencia al módulo.
import time
print "Hola..."
time.sleep(1)
print "...mundo!"
Para saber más sobre el modulo podemos pedir que se imprima la ayuda:
help(time)
Si únicamente necesitamos importar una función podemos usar la construcción
_from_ ... _import_:
``` python
from math import log
print "Log of 100",log(100)
También podemos renombrar el módulo usando el modificador as:
import random as ra
print "Escogeré un valor", ra.choice(['one','two','three'])
Funciones
Por supuesto, algo que esperamos que un lenguaje de programación pueda hacer, es dejarnos definir nuestras propias funciones:
def print_percentage(val):
per=val*100
print str(per)+"%"
Para que nuestra función regrese un valor usamos la palabra return:
def suma_lista(lista):
val=0
for l in lista:
val+=1
return val
Las funciones de Python son completas y nos permiten definir recursividad:
def fib(n):
if n < 2:
return n
return fib(n-2) + fib(n-1)
Una vez definidas las funciones podemos llamarlas en nuestro código:
print_percentage(0.1)
print_percentage(0.02)
print suma_lista(range(20))
print suma_lista(range(200))
fib(10)
fib(20)
Módulos propios
Un módulo en Python en realidad es un programa en Python. Haciendo import de
éste programa podemos tener acceso a las funciones definidas en el código.
Claro en términos organizaciones preferimos que los módulos únicamente
contengan definiciones de funciones y no código a ejecutarse.
Si ponemos las funciones definidas en la sección anterior en un archivo llamado _mimodulo podemos hacer lo siguiente:
import mimodulo
mimodulo.print_percentage(0.1)
mimodulo.print_percentage(0.02)
mimodulo.suma_lista(range(20))
mimodulo.suma_lista(range(200))
mimodulo.fib(10)
mimodulo.fib(20)
Archivos de texto
Procesar archivos en Python es extremadamente fácil.
Para escritura
Primero se abre el archivo con la opción de escritura w, y luego usando la instrucción print, podemos redireccionar la impresión de la pantalla al archivo. Una vez finalizado cerramos el archivo.
archivo=open('tmp','w')
for i in range(10):
print >> archivo, i, "hola mundo!"
archivo.close()
Para lectura
Para lectura es un procedimiento similar:
archivo=open('tmp',"r")
for linea in archivo:
print linea
archivo.close()
El código anterior imprime espacios de más dado que la variable linea contiene la cadena leída con un enter al imprimirla con print se incluye éste. Para corregir esto se puede usar la función strip:
archivo=open('tmp')
for linea in archivo:
linea=linea.strip()
print linea
archivo.close()
Este es un ejemplo donde se procesa aún más la variable linea:
archivo=open('tmp')
for linea in archivo:
line=linea.strip()
bits=line.split()
print bits[-1]
archivo.close()
Más sobre listas
Un patrón de programación muy utilizado, es utilizar una estructura para construir otra estructura paralela. Python hace esto explícito a través del uso de la construcción comprehension lists. Básicamente es un for dentro de una lista. En este caso cada elemento de la lista se usa para crear el nuevo elemento de la nueva lista. Este es el ejemplo para crear una lista con los primeros 100 cuadrados:
lista_original=range(100)
nueva_lista=[i*i for i in lista_original]
print nueva_lista
La construcción también permite filtrar algunos elementos anexando una clausula if:
nueva_lista=[i*i for i in lista_original if i%2==0]
print nueva_lista
Templates para cadenas
Muy parecido al “printf” de C, Python permite usar templates para valores en una cadena. La cadena usa indices para saber el orden de impresión de los valores pasados a través de la función format del template. El siguiente ejemplo, usamos el template para invertir el orden de los argumentos del pasados al format:
lista=[(1,2),(2,3),(3,4),(4,5),(5,6)]
for val0,val1 in lista:
print "{1} {0}".format(val0,val1)
También es posible formatear la conversión de los parámetros:
lista=[(i*1.0/100,j*1.0/100) for i,j in lista]
for val0,val1 in lista:
print "{1:2.3f} {0:2.5f}".format(val0,val1)
Otra función muy útil de las cadenas es join la cual toma como entrada una lista de cadenas y genera una nueva cadena con todos los elementos concatenados pero con el valor de la cadena original intercalado entre los elementos:
lista=["{0:2.3f}".format(i) for i,j in lista ]
print ":".join(lista)
Funciones extra
Una característica muy relevante de Python es que permite definir parámetros opcionales en las funciones:
def count(palabra,ini=0,fin=20):
for i in range(ini,fin):
print palabra,i
La siguientes llamadas son válidas aunque parecieran incompletas:
count("Contando...",10,30)
count("Contando de nuevo...",15)
count("Contando de nuevo otra vez...")
count("Contando de nuevo...",ini=3,fin=8)
count("Contando de nuevo...",fin=5,ini=3)
Uso argumentos de línea
Aunque hoy estamos acostumbrados a utilizar interfaces gráficas para interactuar con nuestros programas, interactuar con la línea de comandos es todavía una gran opción que durante el desarrollo de ciertas herramientas nos facilita la experiencia. Python tiene una librería que facilita la creación de opciones para líneas de comando:
import argparse
p = argparse.ArgumentParser("Ejemplo")
p.add_argument("Archivo_1",default=None,
action="store", help="Archivo Uno")
p.add_argument("Archivo_2",default=None,
action="store", help="Archivo Dos")
p.add_argument("-o", "--opcion1",default=None,type=str,
action="store", dest="op_1",
help="Opcion 2")
p.add_argument("", "--opcion2",default="Valor2",type=str,
action="store", dest="op_2",
help="Opcion 2")
p.add_argument("-n", "--nueva_opcion",default="Valor3",type=str,
action="store", dest="op_3",
help="Argumento")
opts = p.parse_args()
Esta declaración crea un programa que puede soportar las siguiente llamadas desde línea de comando
python programa.py
python programa.py -h
python programa.py archivo1 archivo2
python 12_linea_de_commandos.py -o 1 --opcion2 2 -n 3 archivo1 archivo2
Trabajando con errores
Python tiene un sistema de excepciones que genera un mensaje de error cada vez que se produce uno, pero que además para la ejecución normal de nuestro código:
1/0
Inmediatamente python escribe en pantalla que tipo de error y la línea donde se produce el error.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Aunque generalmente los errores son algo malo para nuestro código podemos trabajar con ellos, usando la construcción try y except. La primera le dice que intente un código, pero si un error ocurre del tipo marcado por except se puede hacer una “reparación” y continuar trabajando:
lista=range(100)
residuos_3={}
for i in lista:
try:
residuos_3[i%3]+=1
except KeyError:
residuos_3[i%3]=1
En este ejemplo, queremos contar cuantas veces los residuos para tres aparecen en los primeros 100 enteros. Para lograr esto, usamos un diccionario que va a contener nuestras cuentas, pero existe la posibilidad de el indice del residuo no este definido, lo que nos marcaría un error de no existencia de la llave en el diccionario. Por esta razón metemos el incremento de nuestro contador en el bloque del try, si hay un error y es del tipo KeyError aprovechamos y creamos el índice faltante inicializado a uno.