You are on page 1of 45

Introducci on a Python

Gonzalo Soriano
gsoriano@fi.uba.ar
30 de junio de 2009
1. Lenguaje interpretado
1.1. Diferencias entre un lenguaje interpretado y uno com-
pilado
Las computadoras entienden un solo lenguaje; binario (tambien llamado
lenguaje de m aquina) por lo que al compilar un programa lo que hacemos es
traducir ese codigo que nosotros escribimos en un lenguaje de alto nivel a algo
que ella pueda interpretar.
Las principales ventajas de usar un lenguaje compilado son que:
Independencia del lenguaje: Una vez que compilamos el codigo fuente y
generamos el archivo binario, dejamos de depender del lenguaje en que se
implemento el programa. Si copiamos ese ejecutable a una computadora
que tenga una arquitectura igual a la maquina donde se lo compilo, este
puede correr sin necesidad del compilador.
Velocidad de ejecuci on: Al traducir el codigo fuente al lenguaje nativo
de la computadora logramos que ella lo entienda directamente y pueda
ejecutarlo con mayor velocidad.
Permite optimizaciones del compilador: El compilador puede usar algo-
ritmos que viendo porciones de nuestro codigo lo optimice mejorando su
velocidad de ejecucion.
Como todo, tambien tiene desventajas:
Dependencia de la plataforma: La independencia que logramos del lengua-
je es a costa de una gran dependencia de la arquitectura en que se compilo
ese codigo fuente. Si nosotros cambiamos, por ejemplo, el sistema opera-
tivo vamos a tener que recompilar todo el programa para poder usarlo.
Lentitud en el desarrollo: Cualquier modicacion que se le haga al progra-
ma puede llevar a recompilar todo el programa, o por lo menos una gran
parte de el. Si estamos desarrollando un programa de gran envergadu-
ra y estamos en una etapa en la que se hacen y prueban modicaciones
constantemente podemos perder mucho tiempo recompilando todo hasta
encontrar la version nal.
1
Una alternativa a usar un lenguaje compilado, es usar un lenguaje interpre-
tado. Las computadoras siguen entendiendo un unico lenguaje, pero ahora lo
que se hace es usar un lenguaje compilado para crear un interprete (tambien
conocido como maquina virtual ), el cual estara entre nuestro codigo fuente y
la computadora cumpliendo la funcion de todo interprete: traducir solo lo que
necesita de un lenguaje a otro. Aca surge la primer diferencia con un lenguaje
compilado; solo traduce lo que necesita en ese momento. Por este motivo es que
puede ser que una porcion del codigo nunca sea traducida al lenguaje maquina.
Como contra, al traducir en el momento y no guardar esas traducciones, puede
suceder que una porcion del codigo lo traduzca varias veces.
Las ventajas de un lenguaje interpretado son:
Independencia de la plataforma: Si queremos correr nuestro programa en
otra computadora, no tenemos que preocuparnos de que la plataforma
sea igual a la nuestra. Solo tenemos que asegurarnos que tenga instal-
ado un interprete para esa plataforma. Y si en un futuro se crea una
nueva plataforma totalmente revolucionaria que tenga un interprete de
ese lenguaje nuestro programa no debera modicarse en una sola lnea y
seguir funcionando perfectamente.
Agilidad en el desarrollo: Como no tenemos que compilar el programa
para hacer pruebas (solo tenemos que correrlo sobre el interprete) es mas
rapido para hacer pruebas y continuar con el desarrollo o buscar el error.
Este tipo de lenguajes tampoco es perfecto y, por supuesto, tambien tiene
desventajas:
Dependencia del lenguaje: Como en los lenguajes compilados la indepen-
dencia del lenguaje creaba una dependencia de la plataforma; en este caso
pasa lo contrario. La independencia de la plataforma la tenemos porque
todo corre sobre la maquina virtual, por lo que sin interprete, no se puede
correr el programa.
Lentitud en la ejecucion: Como toda instruccion tiene que pasar por el
interprete, para que este la traduzca y luego se ejecute es, un poco, mas
lento que los programas compilados.
Algunos ejemplos de lenguajes compilados e interpretados:
Lenguajes compilados Lenguajes interpretados
Pascal Python
C/C++ Java
Fortran C#
1.2. Caractersticas de Python
Algunas de las caractersticas que podemos encontrar en Python son:
Agilidad en el desarrollo I: Es rapido para probar y continuar desarrol-
lando gracias a que cuenta con un interprete que va ejecutando el codigo
a medida que lo escribimos en el. Es muy comodo para probar peque nas
porciones de codigo.
2
Agilidad en el desarrollo II: rapido para programar la simplicidad del
lenguaje y por las herramientas que contamos.
Muy facil de entender lo que hace el programa, ya que el codigo es limpio
y elegante.
Es multiplataforma, por lo que el mismo codigo la mayora de las veces se
puede ejecutar en distintas computadoras y con distintos sistemas opera-
tivos sin modicaciones.
Cuenta con una gran cantidad de modulos con muchas funcionalidades
directamente en el standard.
Es un lenguaje fuertemente tipado pero de asignacion dinamica. Se puede
ver esta ventaja en el ordenamiento de un vector de strings, o enteros, es
lo mismo. Importa el algoritmo, no los tipos.
El principal objetivo que persigue este lenguaje es la facilidad, tanto de
lectura, como de dise no.
1.2.1. The Zeb of Python
Desde la version 2.1.2 de Python, si tratamos de importar el modulo thisnos
muestra las 19 premisas de Python escritas por Tim Peters.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases arent special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless youre Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, its a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- lets do more of those!
La traduccion sera
1
:
1
http://es.wikipedia.org/wiki/Python
3
1. Bello es mejor que feo.
2. Explcito es mejor que implcito.
3. Simple es mejor que complejo.
4. Complejo es mejor que complicado.
5. Plano es mejor que anidado.
6. Ralo es mejor que denso.
2
7. La legibilidad cuenta.
8. Los casos especiales no son tan especiales como para quebrantar las reglas.
9. Aunque lo practico gana a la pureza.
10. Los errores nunca deberan dejarse pasar silenciosamente.
11. A menos que hayan sido silenciados explcitamente.
12. Frente a la ambig uedad, rechaza la tentacion de adivinar.
13. Debera haber una -y preferiblemente solo una- manera obvia de hacerlo.
14. Aunque esa manera puede no ser obvia al principio a menos que usted sea
Holandes
15. Ahora es mejor que nunca.
16. Aunque nunca es a menudo mejor que ya.
17. Si la implementacion es difcil de explicar, es una mala idea.
18. Si la implementacion es facil de explicar, puede que sea una buena idea.
19. Los espacios de nombres (namespaces) son una gran idea Hagamos mas
de esas cosas!
Si bien todas son buenas practicas de programacion, quiero destacar algunas:
Bello es mejor que feo.
Simple es mejor que complejo.
Complejo es mejor que complicado.
La legibilidad cuenta.
Los casos especiales no son tan especiales como para quebrantar las reglas.
Si la implementacion es difcil de explicar, es una mala idea.
2
Me gusta mas: Disperso es mejor que denso.
4
1.3. Estructura de un programa en Python
La estructura de un programa en Python no es tan estricta como puede serlo
en Pascal o en C/C++, ya que no debe comenzar con ninguna palabra reserva-
da, ni con un procedimiento o funcion en particular. Simplemente con escribir
un par de lneas de codigo ya podramos decir que tenemos un programa en
Python.
Lo que es importante destacar es la forma de identicar los distintos bloques de
codigo. En Pascal se dena un bloque de codigo usando las palabras reservadas
Begin y End; en C/C++ se dene mediante el uso de las llaves ({ y }). Sin em-
bargo, en Python, se utiliza la indentacion; es decir, la cantidad de espacios/tabs
que hay entre el comienzo de la lnea y el primer caracter distinto a ellos.
1.4. Interprete Python
El interprete de Python es una herramienta muy util al momento de desar-
rollar, ya que se puede ir probando peque nas porciones del codigo sin necesidad
de hacer todo el programa. Lo unico que hay que hacer para usarlo es tenerlo
instalado y correr el comando python en la consola.
Al hacer eso nos va a aparecer un shell que comenzara con >>>, en el cual
podremos escribir codigo y automaticamente se ira interpretando.
Cuando usamos una estructura selectiva o de repeticion generalmente vamos a
tener que escribir mas de una lnea, por lo que el interprete no va a ejecutar ese
codigo hasta que se lo indiquemos dejando una lnea en blanco, es decir, con solo
un Enter. Para indicarnos que todava no va a ser interpretado va a cambiar el
prompt >>> por ....
Con los procedimientos y funciones hace algo similar, pero con la diferencia que
ese codigo se va a interpretar una vez que lo invoquemos, y no al terminar de
denirlo.
En el siguiente ejemplo vamos a abrir el interprete python.
$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
Type "help", "copyright", "credits" or "license" for more information.
>>>
Crear una lista de elementos que va a tener tres n umeros, dos strings y una
sublista de dos enteros.
$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
Type "help", "copyright", "credits" or "license" for more information.
>>> lista = [1, 2, "12", "34", [5, 6]]
Imprimir la lista por pantalla
$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
Type "help", "copyright", "credits" or "license" for more information.
>>> lista = [1, 2, "12", "34", [5, 6]]
>>> print lista
[1, 2, 12, 34, [5, 6]]
5
Y ahora vamos a multiplicar todos los elementos de la lista por 2.
$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
Type "help", "copyright", "credits" or "license" for more information.
>>> lista = [1, 2, "12", "34", [5, 6]]
>>> print lista
[1, 2, 12, 34, [5, 6]]
>>> for elemento in lista:
... print elemento*2
Ahora tenemos que dejar una lnea en blanco para que el interprete ejecute
nuestro codigo.
$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
Type "help", "copyright", "credits" or "license" for more information.
>>> lista = [1, 2, "12", "34", [5, 6]]
>>> print lista
[1, 2, 12, 34, [5, 6]]
>>> for elemento in lista:
... print elemento*2
...
2
4
1212
3434
[5, 6, 5, 6]
>>>
Vemos que al multiplicar un n umero por 2, nos devuelve el doble del valor
original. Lo mismo hace con el resto de los datos, si multiplicamos una cadena
de caracteres nos repite la misma secuencia de caracteres y los concatena. Para
una lista, crea una lista igual y tambien la concatena a la primera.
Para salir del interprete solo hay que escribir exit(), o en linux apretar Control+
D. Si ahora queremos hacer un programa que haga exactamente lo mismo, po-
dramos crear un archivo llamado ejemplo.py y que su contenido sea:
lista = [1, 2, "12", "34", [5, 6]]
print lista
for elemento in lista:
print elemento*2
Para ejecutarlo tendramos que hacer:
$python ejemplo.py
Y la salida sera:
6
$python ejemplo.py
[1, 2, 12, 34, [5, 6]]
2
4
1212
3434
[5, 6, 5, 6]
Para leer valores ingresados desde el teclado podemos usar la funcion raw_input,
la cual puede recibir una cadena de caracteres a imprimir, lee el valor ingresado
y lo retorna como un string.
>>> variable = raw_input("Ingrese algo: ")
Ingrese algo: 7540
>>> print variable
7540
>>> variable = raw_input()
40
>>> variable = raw_input()
Esta cadena la guardo en variable
>>> print variable
Esta cadena la guardo en variable
>>>
1.4.1. Comentarios
Hay dos reglas que no se deben olvidar nunca:
1. Todos los programas tienen errores, y un codigo que se entienda ayuda a
encontrarlos.
2. Todos los programas sufren modicaciones a lo largo de su vida, al menos
todos aquellos que tienen exito.
Por cualquiera de estas razones es conveniente escribir un codigo claro, legible
y ayudarlo con comentarios para facilitar estas tareas. Lo cual no signica que
a partir de ahora vayan a escribir mas lneas de comentarios que de codigo, ya
que tambien hay que saber que escribir.
Al momento de hacer un comentario hay que pensar en cuanta informacion nue-
va estas aportando, o cuanto mas legible queda el codigo para quien lo tenga
que leer y mantener.
La forma de hacer comentarios en Python es anteponiendo el #, de esa for-
ma, desde ese caracter hasta el n de la lnea se obviaran todos los caracteres
al momento de ejecutar el codigo. Por ejemplo, si tomamos el codigo anterior:
# Cargo una lista que tiene elementos de distintos tipos.
lista = [1, 2, "12", "34", [5, 6]]
# Imprimo la lista por pantalla.
print lista
7
# A todo elemento de la lista lo multiplico por 2 y lo imprimo.
for elemento in lista:
print elemento*2 # Esto tambien es un comentario
# Y esto.
El ejemplo anterior es muy basico, pero tiene dos objetivos:
1. Mostrar como se hace un comentario en Python
2. Mostrar que tipo de comentarios NO se deben hacer.
Los comentarios del ejemplo son los llamados comentarios duplicadores del
codigo, ya que lo unico que hacen es decir que hace el programa lnea por
lnea sin aportar nada nuevo. Si los comentarios son solo una traduccion del
lenguaje que estan usando a su lenguaje nativo, dejan de ser utiles y para colmo
agregamos algo mas que hay que mantener. Si el codigo cambia de forma que
los comentarios queden desactualizados (cosa que es muy com un que pase con
este tipo de comentarios) hay que mantenerlos para que no confundan a quien
lo lee.
Un comentario es util cuando indicamos algo que no es evidente. Por ejemplo,
si vemos el siguiente codigo es difcil entender lo que hace esa lnea.
mult = mat[1][2]*mat[0][1]*mat[2][0]-mat[2][2]*mat[0][1]*mat[1][0]+ \
mat[1][1]*mat[0][0]*mat[2][2]+mat[0][2]*mat[1][0]*mat[2][1]- \
mat[0][2]*mat[1][1]*mat[2][0]-mat[1][2]*mat[2][1]*mat[0][0]
Sin embargo, si a esa lnea le agregamos un comentario, podemos darnos cuenta
facilmente lo que hace.
# Calculo el determinante de una matriz de 3x3.
mult = mat[1][2]*mat[0][1]*mat[2][0]-mat[2][2]*mat[0][1]*mat[1][0]+ \
mat[1][1]*mat[0][0]*mat[2][2]+mat[0][2]*mat[1][0]*mat[2][1]- \
mat[0][2]*mat[1][1]*mat[2][0]-mat[1][2]*mat[2][1]*mat[0][0]
2. Tipos de datos y como manipularlos
2.1. Tipos soportados
Python es un lenguaje fuertemente tipado, pero a la vez tiene la carac-
terstica de tipado dinamico. Es de fuertemente tipado ya que no se permite
usar una variable de un tipo determinado como si fuera de otro, por ejemplo,
no se le puede sumar un string a un entero o otante. Y es tipado dinamico ya
que una misma variable, a lo largo de su existencia, puede ser de distintos tipos.
Por ejemplo, podemos tener una variable del tipo string, y en la lnea siguiente,
a esa variable asignarle un n umero.
Si bien se le puede asignar a una variable valores de distinto tipo, es conveniente
respetar el tipo que se le asigna en una primer instancia y usar siempre ese.
Algunos de los tipos soportados son:
Tipo: Booleano (bool). Solo puede tomar los valores True y False.
Ejemplo:
8
>>> boolean = True
>>> boolean = False
>>> print True and False
False
>>> print True or False
True
>>> print not True
False
>>> print not False
True
>>> type(boolean)
<type bool>
Funciones disponibles:
>>> dir(True)
[__abs__, __add__, __and__, __class__, __cmp__, __coerce__,
__delattr__, __div__, __divmod__, __doc__, __float__, __floordiv__,
__getattribute__, __getnewargs__, __hash__, __hex__, __index__,
__init__, __int__, __invert__, __long__, __lshift__, __mod__,
__mul__, __neg__, __new__, __nonzero__, __oct__, __or__, __pos__,
__pow__, __radd__, __rand__, __rdiv__, __rdivmod__, __reduce__,
__reduce_ex__, __repr__, __rfloordiv__, __rlshift__, __rmod__,
__rmul__, __ror__, __rpow__, __rrshift__, __rshift__, __rsub__,
__rtruediv__, __rxor__, __setattr__, __str__, __sub__, __truediv__,
__xor__]
Tipo: Enteros corto (int)
Ejemplo:
>>> entero = 5
>>> type(entero)
<type int>
Funciones disponibles:
>>> dir(5)
[__abs__, __add__, __and__, __class__, __cmp__, __coerce__,
__delattr__, __div__, __divmod__, __doc__, __float__, __floordiv__,
__getattribute__, __getnewargs__, __hash__, __hex__, __index__,
__init__, __int__, __invert__, __long__, __lshift__, __mod__,
__mul__, __neg__, __new__, __nonzero__, __oct__, __or__, __pos__,
__pow__, __radd__, __rand__, __rdiv__, __rdivmod__, __reduce__,
__reduce_ex__, __repr__, __rfloordiv__, __rlshift__, __rmod__,
__rmul__, __ror__, __rpow__, __rrshift__, __rshift__, __rsub__,
__rtruediv__, __rxor__, __setattr__, __str__, __sub__, __truediv__,
__xor__]
Tipo: Entero largo (long). Se le agrega una L al nal para diferenciarlo de
los enteros cortos.
Ejemplo:
9
>>> entero = 5L
>>> type(entero)
<type long>
Funciones disponibles:
>>> dir(5L)
[__abs__, __add__, __and__, __class__, __cmp__, __coerce__,
__delattr__, __div__, __divmod__, __doc__, __float__, __floordiv__,
__getattribute__, __getnewargs__, __hash__, __hex__, __index__,
__init__, __int__, __invert__, __long__, __lshift__, __mod__,
__mul__, __neg__, __new__, __nonzero__, __oct__, __or__, __pos__,
__pow__, __radd__, __rand__, __rdiv__, __rdivmod__, __reduce__,
__reduce_ex__, __repr__, __rfloordiv__, __rlshift__, __rmod__,
__rmul__, __ror__, __rpow__, __rrshift__, __rshift__, __rsub__,
__rtruediv__, __rxor__, __setattr__, __str__, __sub__, __truediv__,
__xor__]
Tipo: Complejo (complex)
Ejemplo:
>>> complejo = 3 + 5j
>>> complejo += 1 - 2j
>>> print complejo
(4+3j)
>>> complejo *= 1 - 2j
>>> print complejo
(10-5j)
>>> type(complejo)
<type complex>
Funciones disponibles:
>>> dir(5+3j)
[__abs__, __add__, __class__, __coerce__, __delattr__, __div__,
__divmod__, __doc__, __eq__, __float__, __floordiv__, __ge__,
__getattribute__, __getnewargs__, __gt__, __hash__, __init__,
__int__, __le__, __long__, __lt__, __mod__, __mul__, __ne__,
__neg__, __new__, __nonzero__, __pos__, __pow__, __radd__,
__rdiv__, __rdivmod__, __reduce__, __reduce_ex__, __repr__,
__rfloordiv__, __rmod__, __rmul__, __rpow__, __rsub__, __rtruediv__,
__setattr__, __str__, __sub__, __truediv__, conjugate, imag, real]
Tipo: Real o otante (float)
Ejemplo:
>>> real = 3.5
>>> type(real)
<type float>
Funciones disponibles:
10
>>> dir(3.5)
[__abs__, __add__, __class__, __coerce__, __delattr__, __div__,
__divmod__, __doc__, __eq__, __float__, __floordiv__, __ge__,
__getattribute__, __getformat__, __getnewargs__, __gt__, __hash__,
__init__, __int__, __le__, __long__, __lt__, __mod__, __mul__,
__ne__, __neg__, __new__, __nonzero__, __pos__, __pow__, __radd__,
__rdiv__, __rdivmod__, __reduce__, __reduce_ex__, __repr__,
__rfloordiv__, __rmod__, __rmul__, __rpow__, __rsub__, __rtruediv__,
__setattr__, __setformat__, __str__, __sub__, __truediv__]
Tipo: Cadena de caracteres o String (string)
Ejemplo:
>>> cadena = "esta es una cadena de caracteres"
>>> type(cadena)
<type str>
Funciones disponibles:
>>> dir("cadena")
[__add__, __class__, __contains__, __delattr__, __doc__, __eq__,
__ge__, __getattribute__, __getitem__, __getnewargs__, __getslice__,
__gt__, __hash__, __init__, __le__, __len__, __lt__, __mod__,
__mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__,
__rmod__, __rmul__, __setattr__, __str__, capitalize, center,
count, decode, encode, endswith, expandtabs, find, index,
isalnum, isalpha, isdigit, islower, isspace, istitle, isupper,
join, ljust, lower, lstrip, partition, replace, rfind, rindex,
rjust, rpartition, rsplit, rstrip, split, splitlines, startswith,
strip, swapcase, title, translate, upper, zfill]
Tipo: Unicode (unicode)
Ejemplo:
>>> cadena = u"esta cadena es de tipo Unicode"
>>> type(cadena)
<type unicode>
Funciones disponibles:
>>> dir(u"cadena unicode")
[__add__, __class__, __contains__, __delattr__, __doc__, __eq__,
__ge__, __getattribute__, __getitem__, __getnewargs__, __getslice__,
__gt__, __hash__, __init__, __le__, __len__, __lt__, __mod__,
__mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__,
__rmod__, __rmul__, __setattr__, __str__, capitalize, center,
count, decode, encode, endswith, expandtabs, find, index, isalnum,
isalpha, isdecimal, isdigit, islower, isnumeric, isspace, istitle,
isupper, join, ljust, lower, lstrip, partition, replace, rfind,
rindex, rjust, rpartition, rsplit, rstrip, split, splitlines,
startswith, strip, swapcase, title, translate, upper, zfill]
Tipo: Listas (list). Una lista es un vector de elementos que no necesaria-
mente tienen que ser todos del mismo tipo.
Ejemplo:
11
>>> lista = ["Elemento1", "Elemento2", 3, 4, 3.5, u"Unicode String", type(5),
5L, [1, 2, 3]]
>>> type(lista)
<type list>
Funciones disponibles:
>>> dir([])
[__add__, __class__, __contains__, __delattr__, __delitem__,
__delslice__, __doc__, __eq__, __ge__, __getattribute__, __getitem__,
__getslice__, __gt__, __hash__, __iadd__, __imul__, __init__,
__iter__, __le__, __len__, __lt__, __mul__, __ne__, __new__,
__reduce__, __reduce_ex__, __repr__, __reversed__, __rmul__,
__setattr__, __setitem__, __setslice__, __str__, append, count,
extend, index, insert, pop, remove, reverse, sort]
Tipo: Tuplas (tuple). Las tuplas son listas inmutables. Es decir, listas que
una vez que se crean, no se pueden modicar.
Ejemplo:
>>> tupla = ("Elemento1", "Elemento2", 3, 4, 3.5, u"Unicode String", type(5),
5L, [1, 2, 3])
>>> type(tupla)
<type tuple>
Funciones disponibles:
>>> dir(())
[__add__, __class__, __contains__, __delattr__, __doc__, __eq__,
__ge__, __getattribute__, __getitem__, __getnewargs__, __getslice__,
__gt__, __hash__, __init__, __iter__, __le__, __len__, __lt__,
__mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__,
__rmul__, __setattr__, __str__]
Tipo: Diccionarios o Hash

s (dict). Los diccionarios son estructuras a las


que se le puede asignar una clave y un valor asociado para ella. Esa clave puede
ser de cualquier tipo inmutable, por ejemplo: strings, n umeros enteros, n umeros
complejos, n umeros reales, booleanos y tuplas; pero no listas ni diccionarios ya
que son mutables. Ademas, no es necesario que todas las claves sean del mismo
tipo.
Ejemplo:
>>> dic = {"clave": "valor", "clave2": 5, 1:3, 2.5:u"otro valor", 3+5j:7L,
"lista": [1,2,3], "dict":{1:2, 2:3, 4:5}, "y ahora una tupla":(1,2,2),
(1,2,3,4):"la clave es una tupla"}
>>> print dic
{2.5: uotro valor, 1: 3, y ahora una tupla: (1, 2, 2), clave2: 5, (3+5j): 7L,
clave: valor, dict: {1: 2, 2: 3, 4: 5}, lista: [1, 2, 3],
(1, 2, 3, 4): la clave es una tupla}
>>> type(dic)
<type dict>
Funciones disponibles:
12
>>> dir({})
[__class__, __cmp__, __contains__, __delattr__, __delitem__, __doc__,
__eq__, __ge__, __getattribute__, __getitem__, __gt__, __hash__,
__init__, __iter__, __le__, __len__, __lt__, __ne__, __new__,
__reduce__, __reduce_ex__, __repr__, __setattr__, __setitem__,
__str__, clear, copy, fromkeys, get, has_key, items, iteritems,
iterkeys, itervalues, keys, pop, popitem, setdefault, update,
values]
2.1.1. Conversion entre tipos
Para convertir a un n umero entero se puede usar la funcion int(n), a la
cual se le puede pasar un string o un oat, pero no un string que sea un oat.
>>> int("12")
12
>>> int(12.3)
12
>>> int(12.7)
12
>>> int("12.3")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 12.3
A esta funcion tambien se le puede pasar un n umero como string y una base
(int(n, base)) y convierte ese valor n que se encuentra en la base base a
decimal.
>>> int("10", 2)
2
>>> int("10", 16)
16
>>> int("a", 16)
10
>>> int("af65b", 16)
718427
>>> int("1101", 2)
13
As como pudimos pasar a enteros, tambien podemos pasar a n umeros
otantes, pero no tenemos tantas alternativas como antes. Para eso podemos
usar la funcion float(string) que recibe una cadena de caracteres y retorna un
oat.
>>> float("12")
12.0
>>> float("12.5723")
12.5723
>>> float("12.7")
12.699999999999999
13
>>> float("1e")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for float(): 1e
>>>
Tambien se le puede pasar un n umero entero y lo convierte a otante:
>>> float(12)
12.0
Para convertir cualquier variable a string podemos usar la funcion str() que
recibe cualquier cosa y hace su mejor intento para convertirla. A diferencia del
resto, esta funcion nunca va a fallar por no saber como convertir algo. Puede
pasar que con alg un tipo en particular no nos devuelva el resultado que quere-
mos, pero seguro que nos va a devolver una representacion de lo que le pasamos
en string.
>>> str(5)
5
>>> str(5.4)
5.4
>>> str(5L)
5
>>> str(True)
True
>>> str()

>>> str([1, 2, 3, "uno"])


"[1, 2, 3, uno]"
>>> str([1, 2, 3, "uno", 5.7])
"[1, 2, 3, uno, 5.7000000000000002]"
>>> str((1, 2, 3, "uno", 5.7))
"(1, 2, 3, uno, 5.7000000000000002)"
>>> str({1:"uno", 2:"dos", 3:"tres"})
"{1: uno, 2: dos, 3: tres}"
Una alternativa para insertar valores en un string es, al que en C, indican-
do en la cadena donde queremos que vaya con un % y despues pasar todos los
parametros juntos. Al igual que en C, cuando marcamos la posicion donde quer-
emos que se ingrese alg un valor, tambien vamos a tener que indicar el tipo de
ese parametro; y ellos pueden ser:
14
Indicador Tipo:
%c Solo un caracter.
%s Cadena de caracteres.
%d o %i o %u 0 %ld 0 %lu Entero con signo.
%nd Entero con signo ocupando n
3
espacios.
%.nd Entero con signo ocupando n lugares, completando con 0.
%f Float o real.
%.nf Float o real con solo n decimales.
%e Float o double, con notacion cientca.
%.ne Float o double, con notacion cientca, con solo n decimales.
%g Coma otante, usando la notacion que requiera menor espacio.
%x Hexadecimal.
Algunos ejemplos:
>>> print "%c" % s
s
>>> print "%c" % ss
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: %c requires int or char
>>> print "%s" % ss
ss
>>> "%d" % 5
5
>>> "%d" % -5
-5
>>> "%0.2d" % 5
05
>>> "%5d" % 5
5
>>> 5 5 5 5 5 0005 0005
5 5 5 5 5 0005 0005
>>> " %d %i %s %ld %lu %0.4d %4d" % (5, 5, 5, 5, 5, 5, 5)
5 5 5 5 5 0005 5
>>> " %d %i %s %ld %lu %0.4d %4d" % (-5, -5, -5, -5, -5, -5, -5)
-5 -5 -5 -5 -5 -0005 -5
>>> " %d %i %s %ld %lu %0.4d %4d" % (5L, 5L, 5L, 5L, 5L, 5L, 5L)
5 5 5 5 5 0005 5
>>> "%f" % -5
-5.000000
>>> "%.2f" % -5.345
-5.34
>>> "%x" % 123
7b
>>> "%x" % -123
-7b
>>>
Ademas se pueden mezclar con los siguientes caracteres:
15
Caracter Descripcion
\n Caracter n de lnea.
\r Caracter retorno del carro.
\t Caracter tabulador horizontal.
\v Caracter tabulador vertical.
\a Timbre.
\\ Barra invertida.
\" Comillas.
\ Apostrofe.
Algunos ejemplos:
>>> print "Algoritmos \r mundo"
mundotmos
>>> print "\a"
>>> print "Hola\tmundo"
Hola mundo
>>> print "Hola\vmundo"
Hola
mundo
>>> print "\\"
\
>>> print "\"

>>> print "\""


"
>>>
Si lo que queremos es juntar todas las palabras de una lista o tupla podemos
usar la funcion join() de la siguiente forma:
>>> " ".join(("Algoritmos", "y", "Programacion", "I"))
Algoritmos y Programacion I
>>> "".join(["Algoritmos", "y", "Programacion", "I"])
AlgoritmosyProgramacionI
>>> " ".join(["Algoritmos", "y", "Programacion", "I"])
Algoritmos y Programacion I
>>>> "##separador##".join(["Algoritmos", "y", "Programacion", "I"])
Algoritmos##separador##y##separador##Programacion##separador##I
Y como sucede generalmente, si hay una funcion que va en un sentido existe
otra que va en el sentido inverso. Para parsear un string y obtener una lista
podemos usar la funcion split. Por defecto el separador es el espacio, por lo que
si le pasamos una oracion, nos la separara por palabras.
>>> "Hola mundo".split()
[Hola, mundo]
>>> "Hola mundo".split(",")
[Hola mundo]
>>> "Hola,mundo,".split(",")
16
[Hola, mundo, ]
>>> "Hola,mundo".split(",")
[Hola, mundo]
>>> "Hola mundo ".split()
[Hola, mundo]
Tambien se puede obtener partes de un string indicando su posicion respecto
del inicio o el rango que se desea obtener. Para indicar un rango se pone primero
la posicion del comienzo, despues un separador que sera el : y por ultimo la
posicion del nal. Si no se le pasa la posicion donde comienza el rango, asume
que ese valor es 0; y si la posicion que no se le pasa es la del nal, asume que es
hasta el nal del string.
>>> "Hola mundo"[2]
l
>>> "Hola mundo"[2:4]
la
>>> "Hola mundo"[2:3]
l
>>> "Hola mundo"[0:4]
Hola
>>> "Hola mundo"[:4]
Hola
>>> "Hola mundo"[5:]
mundo
As como podemos saber la posicion desde el inicio de la cadena de carac-
teres, tambien podemos indicar la posicion respecto del ultimo caracter:
Cadena de caracteres: H o l a m u n d o
Posicion desde el inicio: 0 1 2 3 4 5 6 7 8 9
Posicion desde el nal: -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
>>> "Hola mundo"[-1]
o
>>> "Hola mundo"[:-1]
Hola mund
>>> "Hola mundo"[0:4]
Hola
>>> "Hola mundo"[0:-6]
Hola
>>> "Hola mundo"[:-6]
Hola
>>> "Hola mundo"[:4]
Hola
Al igual que con los strings, tambien se le pueden especicar rangos y posi-
ciones para las listas y tuplas.
>>> [3, 5, 1, 7, 15, 11][4]
15
>>> [3, 5, 1, 7, 15, 11][-2]
17
15
>>> [3, 5, 1, 7, 15, 11][1:3]
[5, 1]
>>> [3, 5, 1, 7, 15, 11][1:5]
[5, 1, 7, 15]
>>> [3, 5, 1, 7, 15, 11][1:-1]
[5, 1, 7, 15]
>>> (3, 5, 1, 7, 15, 11)[4]
15
>>> (3, 5, 1, 7, 15, 11)[-2]
15
>>> (3, 5, 1, 7, 15, 11)[1:3]
(5, 1)
>>> (3, 5, 1, 7, 15, 11)[1:5]
(5, 1, 7, 15)
Una forma muy sencilla de crear una lista con valores consecutivos es usando
la funcion range([piso], techo); que puede recibir uno o dos parametros. Si se
le pasa un solo parametro la funcion devuelve una lista que tendra todos los
n umeros que sean iguales o mayores a 0 y menores a ese n umero.
>>> range(3)
[0, 1, 2]
>>> range(-1)
[]
En cambio, si se le pasan dos parametros nos va a devolver una lista que
tendra todos los n umeros que sean iguales o mayores al primero y menores al
segundo.
>>> range(3,7)
[3, 4, 5, 6]
>>> range(-7,-1)
[-7, -6, -5, -4, -3, -2]
Otras funciones utiles son las que convierten a listas (list()) o tuplas (tuple()),
y pueden hacerlo desde una lista, una tupla, un string o un diccionario (en este
caso solo obtendremos sus claves).
>>> tuple((1, 2, 3))
(1, 2, 3)
>>> tuple([1,2,3,4])
(1, 2, 3, 4)
>>> tuple("")
()
>>> tuple("Hola mundo.")
(H, o, l, a, , m, u, n, d, o, .)
>>> tuple({1:"uno", 2:"dos", 3:"tres"})
(1, 2, 3)
>>> list((1, 2, 3))
18
[1, 2, 3]
>>> list([1,2,3,4])
[1, 2, 3, 4]
>>> list("Hola mundo.")
[H, o, l, a, , m, u, n, d, o, .]
>>> list({1:"uno", 2:"dos", 3:"tres"})
[1, 2, 3]
Otra forma de obtener una lista con todas las claves de un diccionario es a traves
de la funcion keys().
>>> {1:"uno", 2:"dos", 3:"tres"}.keys()
[1, 2, 3]
Y si podemos obtener sus claves, tambien podemos obtener los valores asociados
a esas claves. Para esto tendremos que hacer uso de la funcion values()
>>> {1:"uno", 2:"dos", 3:"tres"}.values()
[uno, dos, tres]
2.1.2. Algunas funciones utiles para conocer un poco mas lo que
usamos.
Otra herramienta de Python muy util es la de poder averiguar informacion
sobre lo que usamos en tiempo de ejecucion, aunque tambien para eso podemos
usar el interprete.
Las funciones que vamos a usar son dir(), __doc__ y help().
La funcion dir() nos da informacion de como manipular ese objeto. Por ejemplo,
si a esta funcion le pasamos un string nos muestra las funciones que le podemos
aplicar:
>>> dir("string")
[__add__, __class__, __contains__, __delattr__, __doc__, __eq__,
__ge__, __getattribute__, __getitem__, __getnewargs__, __getslice__,
__gt__, __hash__, __init__, __le__, __len__, __lt__, __mod__,
__mul__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__,
__rmod__, __rmul__, __setattr__, __str__, capitalize, center,
count, decode, encode, endswith, expandtabs, find, index,
isalnum, isalpha, isdigit, islower, isspace, istitle, isupper,
join, ljust, lower, lstrip, partition, replace, rfind, rindex,
rjust, rpartition, rsplit, rstrip, split, splitlines, startswith,
strip, swapcase, title, translate, upper, zfill]
La funcion __doc__ nos da informacion de como usar una funcion en particular.
Para poder conseguir esa informacion primero alguien la tiene que cargar, y
eso se hace escribiendo un comentario que comience y termine con tres comillas
dobles(""").
Por ejemplo, si queremos conocer un poco mas la funcion find() de un string
podramos hacer:
>>> print "string".find.__doc__
S.find(sub [,start [,end]]) -> int
19
Return the lowest index in S where substring sub is found,
such that sub is contained within s[start:end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
Y por ultimo, nos queda la funcion help() que al invocarla nos muestra las
funciones para manipular esa variable con una descripcion similar a la que nos
da __doc__
>>> help("string")
Help on module string:
NAME
string - A collection of string operations (most are no longer used).
FILE
/usr/lib/python2.5/string.py
MODULE DOCS
http://www.python.org/doc/current/lib/module-string.html
DESCRIPTION
Warning: most of the code you see here isnt normally used nowadays.
Beginning with Python 1.6, many of these functions are implemented as
methods on the standard string object. They used to be implemented by
a built-in module called strop, but strop is now obsolete itself.
Public module variables:
...
CLASSES
__builtin__.object
Template
class Template(__builtin__.object)
| A string class for supporting $-substitutions.
|
| Methods defined here:
|
| __init__(self, template)
|
| safe_substitute(self, *args, **kws)
|
| substitute(self, *args, **kws)
|
| ...
20
FUNCTIONS
atof(s)
atof(s) -> float
Return the floating point number represented by the string s.
atoi(s, base=10)
atoi(s [,base]) -> int
Return the integer represented by the string s in the given
base, which defaults to 10. The string s must consist of one
or more digits, possibly preceded by a sign. If base is 0, it
is chosen from the leading characters of s, 0 for octal, 0x or
0X for hexadecimal. If base is 16, a preceding 0x or 0X is
accepted.
atol(s, base=10)
atol(s [,base]) -> long
...
find(s, *args)
find(s, sub [,start [,end]]) -> in
Return the lowest index in s where substring sub is found,
such that sub is contained within s[start,end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
...
3. Estructuras de control
3.1. Equivalencias de estructuras de control entre Python,
Pascal y C
Al igual que los lenguajes vistos, en Python tambien existen estructuras para
controlar el ujo del codigo que se va a ejecutar.
3.1.1. if
La estructura selectiva if es similar a las vistas, pero a diferencia de Pascal o
C, ya no se marca el bloque de ejecucion con un Begin ... end o unas { ... }
sino que se utiliza la indentacion.
Pascal
if (condicion) then
accion;
o
21
if (condicion) then
begin
accion1;
accion2;
...
accionN;
end;
C
if (condicion)
accion;
o
if (condicion)
{
accion1;
accion2;
...
accionN;
}
Python
if (condicion):
accion1;
accion2;
...
accionN;
A diferencia de Pascal y C, en Python no hay diferencia entre poner una sola
accion o varias. Ademas, es obligatorio que las acciones esten todas equidistantes
del comienzo de la lnea y a su vez, que esa distancia sea mayor que la distancia
del inicio al if.
>>> if 3<4:
... print 1
... print 2
File "<stdin>", line 3
print 2
^
IndentationError: unindent does not match any outer indentation level
>>> if 3<4:
... print 0
File "<stdin>", line 2
print 0
^
IndentationError: expected an indented block
Otra diferencia es que para comparar si un valor se encuentra dentro de un
rango se puede hacer de una forma mas sencilla:
Pascal
22
if 3 > 2 and 2 > 1 then
writeln(2 esta entre 3 y 1.);
C
if ((3 > 2) && (2 > 1))
printf("2 esta entre 3 y 1.");
Python
if 3 > 2 and 2 > 1:
print "2 esta entre 3 y 1."
o
if 3 > 2 > 1:
print "2 esta entre 3 y 1."
Como la mayora de los lenguajes, la estructura de seleccion if no solo nos
da la posibilidad de elegir que codigo ejecutar si una condicion es verdadera,
sino que tambien podemos elegir otra porcion de codigo para el caso de que la
condicion sea falsa.
if a > b:
print "a es mayor que b"
else:
print "b es mayor que a"
Muchas veces si la condicion es falsa queremos evaluar otras condiciones, por
lo que anidamos este tipo de estructuras poniendo if

s en los else

s.
if mes == 1 and dia <= 31:
print "Fecha OK"
else:
if mes == 2 and dia <= 28:
print "Fecha OK"
else:
if mes == 3 and dia < 31:
print "Fecha OK"
...
Para que esto quede mas compacto y, tal vez, mas comprensible, Python nos
da la posibilidad de expresar los else if poniendo simplemente elif:
if mes == 1 and dia <= 31:
print "Fecha OK"
elif mes == 2 and dia <= 28:
print "Fecha OK"
elif mes == 3 and dia < 31:
print "Fecha OK"
...
23
Y como si todo esto fuera poco, tambien se puede puede preguntar si un
valor esta en una lista. Con los lenguajes que vimos hasta el momento, para
saber si un elemento pertenece a una lista tenamos que recorrerla toda (o por
lo menos hasta encontrarlo) y jarnos uno por uno si es lo que buscabamos. En
Python es tan sencillo como preguntar si un elemento esta en una lista:
>>> l = range(-7,-1)
>>> if -2 in l:
... print "OK"
... else:
... print "No OK"
...
OK
>>> if 2 in l:
... print "OK"
... else:
... print "No OK"
...
No OK
Otra forma de usar el if es como se usa el operador ? en C.
variable = valor1 if condicion else valor2
que le asignara el valor1 si la condicion es verdadera y valor2 en caso
contrario.
Por ejemplo:
>>> num = 5
>>> espar = True if (num % 2 == 0) else False
>>> print espar
False
>>> num = 6
>>> espar = True if (num % 2 == 0) else False
>>> print espar
True
3.1.2. case
En Python no existe una estructura como seran el case en Pascal o el switch
en C y es porque no se lo usa tanto. Ademas, podemos usar los if anidados para
obtener una estructura a un mas potente que un simple discriminador de valores
de una unica variable.
3.1.3. for
Aqu se encuentra la estructura con mayor diferencia entre los 3 lenguajes
vistos en el curso. Por un lado, en Pascal tenemos una estructura que es muy
simple de entender, casi como uno lo dira, pero muy limitada:
for variable_iteracion:=valor_inicial to valor_final do
begin
24
accion1;
accion2;
...
accionN;
end;
Por otro lado, en C esta misma estructura es mucho mas potente, pero a
costa de sacricar un poco de legibilidad:
for (condicion inicial; condicion de corte; modificacion de la variable)
{
accion1;
accion2;
...
accionN;
}
Por lo que Python adopto una tercer forma tratando capturar lo mejor de
cada una de ellas; siempre priorizando la claridad del codigo.
for elemento in lista:
accion1
accion2
...
accionN
Por lo que ahora, recorrer todos los elementos de una lista y trabajar con
ellos (por ejemplo imprimir el doble de cada uno) es mas facil.
>>> lista = [1, 2, "12", "34", [5, 6]]
>>> print lista
[1, 2, 12, 34, [5, 6]]
>>> for elemento in lista:
... print elemento*2
...
2
4
1212
3434
[5, 6, 5, 6]
>>>
Y que pasa si quiero hacer un for para que simplemente muestre los
primeros 50 enteros no negativos, o los n umeros del 20 al 30?. La respuesta
esta unas cuantas hojas antes: range().
Para imprimir los primeros 50 n umeros enteros no negativos:
for i in range(50):
print i
Para imprimir los n umeros que van del 20 al 30:
25
for i in range(20, 31):
print i
Recordemos que cuando invocamos la funcion range nos devuelve una lista
que tiene todos los valores comprendidos entre el piso (0 si no se lo pasamos) y
el techo (sin incluir este ultimo).
List comprehensions:
List comprehensions o la comprension de listas es una estructura para construir
una lista a partir de los elementos de otra. A esos elementos podemos aplicarles
una funcion que me devuelva alg un elemento, como multiplicarlos por 2, y/o
ltrarlos con un if para que solo pasen los que cumplen con alguna condicion
en particular.
Por ejemplo, si queremos una lista que tenga el cuadrado de los primeros 16
n umeros podemos hacer:
>>> lista = [ i**2 for i in range(16)]
>>> print lista
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225]
Ahora supongamos que queremos tener solo el cuadrado de los elementos
impares:
>>> cuad_impares = [ i**2 for i in range(16) if (i%2 == 1)]
>>> print cuad_impares
[1, 9, 25, 49, 81, 121, 169, 225]
Si ahora queremos combinar todas las letras de una lista con las letra de una
segunda lista tambien podramos usar list comprehensions:
>>> l1 = ["a", "b", "c"]
>>> l2 = ["d", "e"]
>>> l = [ e1+e2 for e1 in l1 for e2 in l2]
>>> print l
[ad, ae, bd, be, cd, ce]
Y por ultimo, vamos a ver como podramos sumar el cuadrado de todos los
elementos pares de una lista con todos los impares de la misma lista.
>>> l = range(5)
>>> [e1**2 + e2**2 for e1 in l if (e1 % 2 == 0) for e2 in l if (e2 % 2 == 1)]
[1, 9, 5, 13, 17, 25]
Y podemos ver que
(1, 9, 5, 13, 17, 25) = (0
2
+ 1
2
, 0
2
+ 3
2
, 2
2
+ 1
2
, 2
2
+ 1
2
, 2
2
+ 3
2
, 4
2
+ 1
2
, 4
2
+ 3
2
)
El uso de list comprehensions puede ser muy util (no en los ejemplos que
vimos), pero tengan en cuenta que no siempre el codigo queda mas legible y
entendible para el proximo que lo tenga que leer.
26
3.1.4. while
La estructura que conserva mas similitudes a las vistas en Pascal o C es el
while.
while <condicion>:
accion1
accion2
...
accionN
Por ejemplo:
>>> print "Ingrese una letra:"
Ingrese una letra:
>>> letra = raw_input()
a
>>> while letra < g:
... print "La letra es menor a g, ingrese otra:"
... letra = raw_input()
...
La letra es menor a g, ingrese otra:
a
La letra es menor a g, ingrese otra:
c
La letra es menor a g, ingrese otra:
d
La letra es menor a g, ingrese otra:
z
>>>
Obviamente se pueden usar las mismas condiciones que en un if: Preguntar
si un valor esta en una lista:
>>> lista = [3, 2, 5, 7, 1, 9]
>>> while 7 in lista:
... # Saco el ultimo elemento de la lista
... lista = lista[:-1]
...
>>> print lista
[3, 2, 5]
>>>
O que un valor se encuentre dentro de un rango.
>>> num = int(raw_input("Ingrese un numero: "))
Ingrese un numero: 5
>>> while 1 < num < 10:
... num = int(raw_input("Ingrese un numero: "))
...
Ingrese un numero: 7
Ingrese un numero: 4
27
Ingrese un numero: 9
Ingrese un numero: 2
Ingrese un numero: 15
>>>
3.1.5. repeat
As como no existe un equivalente para el case, tampoco existe otro para el
repeat de Pascal o el do while de C, y, supongo, que los motivos son similares.
4. Programaci on modular
4.1. Procedimientos y funciones
Una de las premisas de Python era que La legibilidad cuenta, y el uso de
procedimientos y funciones ayudan mucho en que un codigo sea legible.
En Python no existen los procedimientos: son todas funciones. Incluso, aunque
nosotros no devolvamos ning un valor, Python lo hara por nosotros.
La forma de devolver valores es, al igual que en C, usando la palabra reservada
return y el valor a retornar. Y de igual forma, una vez que se ejecuta esa sen-
tencia, no se ejecuta ninguna sentencia mas de esa funcion; sin importar si esta
dentro de un ciclo o todava no hayamos hecho nada.
La denicion de una funcion comienza usando la palabra reservada def, y con-
tinua dejando un espacio, poniendo el nombre de la funcion
4
, los parametros
entre parentesis
5
y un dos puntos para terminar la lnea. En las lneas que le
siguen va el codigo de la funci on, que, al igual que para las estructuras de con-
trol, la forma en que se indica el bloque de codigo que se tiene que ejecutar es
haciendo uso de la indentacion.
def nombre_funcion(param1, param2, ... , paramN):
sentencia1
sentencia2
...
sentenciaN
Donde una de esas sentencias puede tener el return.
Por ejemplo, si ahora queremos hacer la funcion que calcula el factorial de un
n umero haramos algo por el estilo:
def factorial(n):
for i in range(1,n):
n *= i
return n
Y la forma de usarla es igual que en el resto de los lenguajes, invocamos la
funcion y el resultado podemos asignarselo a una variable o no.
4
Tiene que cumplir las mismas reglas para las variables, puede empezar con cualquier letra
y el y despues le puede seguir cualquier caracter alfanumerico mas el .
5
Los parentesis son obligatorios por mas que no se pasen par ametros
28
# Calculo el factorial de 5 y guardo el resultado en la varaible fac_5.
fac_5 = factorial(5)
# Calculo el factorial de 10 sin guardarlo en ninguna variable.
factorial(10)
Y si en lugar de quererlo hacer iterativo lo quisieramos hacer usando recur-
sividad podramos hacer:
def factorial_rec(n):
if n == 0:
return 1
else:
return n*factorial_rec(n-1)
# Esta lnea ya esta fuera de la funcion y pertenece al bloque principal.
print factorial_rec(5)
Si ahora quisieramos hacer una funcion que haga la b usqueda binaria sobre
una lista de enteros podramos hacer:
>>> def binaria(lista_enteros, clave):
... min = 0
... max = len(lista_enteros) - 1
... centro = (min + max) / 2
... while (lista_enteros[centro] != clave) and (min < max):
... if lista_enteros[centro] > clave:
... max = centro -1
... else:
... min = centro + 1
... centro = (min + max) / 2
... if lista_enteros[centro] == clave:
... return centro
... else:
... return -1
...
>>> binaria([1,2,3,4,5,6,7,8,9], 3)
2
>>> binaria([1,2,3,4,5,6,7,8,9], -5)
-1
Y que pasara si ahora queremos hacer una b usqueda binaria sobre una lista
de strings?.
>>> binaria(["Algoritmos", "Programacion", "Y"], "Y")
2
>>> binaria(["Algoritmos", "Programacion", "Y"], "esta no esta")
-1
Como se puede ver en los ejemplos anteriores, en ning un momento pusimos
el tipo de los parametros que recibe la funcion por lo que en Python no es nece-
sario copiar funciones solo para cambiar el tipo de uno de ellos.
29
Otra ventaja de Python respecto a Pascal es que, al igual que en C, se pueden
denir valores por defecto para los parametros de una funcion. Es decir, si no se
le pasa un valor, ese parametro toma el valor que denio el programador en el
momento que escribio el codigo. La forma de hacerlo es igual que en C, simple-
mente hay que ponerle el signo igual seguido del valor por defecto y, en caso de
que la funcion reciba alg un otro parametro despues de el tambien debe tener un
valor por defecto. Es decir, los parametros que tienen valores por defecto solo
pueden ocupar las ultimas posiciones.
>>> def imprimir_parametros(param1, param2, param3=5, param4="es el cuarto parametro", param5=False):
... print param1, param2, param3, param4, param5
...
>>> imprimir_parametros(1,2,3,4,5)
1 2 3 4 5
>>> imprimir_parametros(1,2,3, 4)
1 2 3 4 False
>>> imprimir_parametros(1,2,3)
1 2 3 es el cuarto parametro False
>>> imprimir_parametros(1,2)
1 2 5 es el cuarto parametro False
>>> imprimir_parametros(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: imprimir_parametros() takes at least 2 arguments (1 given)
>>>
Pero a diferencia de C, en Python no es necesario pasarle todos los paramet-
ros hasta el que nosotros que tome un valor distinto del default, podemos indi-
carlo igualando el nombre del parametro formal a un valor o una variable:
>>> imprimir_parametros(1,2, param5="Este el parametro5")
1 2 5 es el cuarto parametro Este el parametro5
>>>
Incluso, haciendo uso de lo que vimos recien, ni siquiera es necesario pasarle
los parametros en orden:
>>> imprimir_parametros(param5=1, param3=2, param1=3, param2=4, param4=5)
3 4 2 5 1
>>>
Cuando comenzamos a hablar de procedimientos y funciones en Python, di-
jimos que eran todas funciones ya que siempre retornaban alg un valor, pero
vemos en imprimir_parametros que en ning un momento se hace un return;
entonces era mentira lo que habamos dicho?. Obviamente, no. Pero entonces,
que devuelve si no tiene un return?. La respuesta es simple; nada. Pero el valor
nada, que en Python se llama None. Este valor es el equivalente al null de C o
nill de Pascal.
30
>>> resultado = imprimir_parametros(1,2,3,4,5)
1 2 3 4 5
>>> print resultado
None
>>>
Tambien podramos hacer un procedimiento que pida el ingreso de alg un
dato, verique que se encuentre algunos valores posibles y nos devuelva la opcion
elegida.
>>> def confirmar(msg, opciones_validas=["S", "N"], msg_error="Error!!!"):
... aux = raw_input(msg)
... while not aux in opciones_validas:
... print msg_error
... aux = raw_input(msg)
... return aux
...
>>> opcion = confirmar("Seguro que quiere salir?.")
Seguro que quiere salir?.g
Error!!!
Seguro que quiere salir?.g
Error!!!
Seguro que quiere salir?.s
Error!!!
Seguro que quiere salir?.S
>>> print opcion
S
>>> opcion = confirmar("Seguro que quiere salir?.", msg_error="Error. Las opciones validas son: S y N.")
Seguro que quiere salir?.g
Error. Las opciones validas son: S y N.
Seguro que quiere salir?.s
Error. Las opciones validas son: S y N.
Seguro que quiere salir?.S
>>> print opcion
S
>>> def Menu():
... print "1. Opcion 1"
... print "2. Opcion 2"
... print "3. Opcion 3"
... confirmar("", ["1", "2", ""3], "Error!!!!, Las opciones validas son: " + str(range(1,4)))
...
>>> Menu()
1. Opcion 1
2. Opcion 2
3. Opcion 3
g
Error!!!!, Las opciones validas son: [1, 2, 3]
s
Error!!!!, Las opciones validas son: [1, 2, 3]
5
31
Error!!!!, Las opciones v alidas son: [1, 2, 3]
1
>>>
Una cosa que puede ser muy util es asignarle una funcion a una variable,
ya que tambien existe el tipo de dato funcion. La forma de hacerlo es similar
a como asignamos el valor de otra variable, a la izquierda ponemos la variable,
luego el signo igual y por ultimo el nombre de la funcion.
>>> def sumar(num1, num2):
... return num1+num2
...
>>> print sumar(1,2)
3
>>> type(sumar)
<type function>
>>> variable = sumar
>>> type(variable)
<type function>
>>> print variable(1,2)
3
En el ejemplo anterior podemos ver como al asignarle el nombre de la fun-
cion a una variable, despues usar esa variable como si llamaramos a la misma
funcion.
La utilidad de esta funcionalidad no es usar la misma funcion con otro nombre
para confundir a un mas a quien tenga que leer el codigo, sino, poder elegir en
tiempo de ejecucion que funcion invocar. Por ejemplo, si queremos hacer una
funcion que haga la b usqueda binaria en una lista ordenada en forma ascendente
podramos usar la funcion que escribimos antes:
def binaria(lista_enteros, clave):
min = 0
max = len(lista_enteros) - 1
centro = (min + max) / 2
while (lista_enteros[centro] != clave) and (min < max):
if lista_enteros[centro] > clave:
max = centro -1
else:
min = centro + 1
centro = (min + max) / 2
if lista_enteros[centro] == clave:
return centro
else:
return -1
Ahora supongamos que queremos hacer una b usqueda sobre una lista que
esta ordenada en forma descendente, entonces ya no nos servira nada de lo que
tenemos y tendramos que copiar el mismo codigo cambiando solamente el signo
32
mayor por un menor y tendramos dos funciones casi iguales que solo diferiran
en un solo caracter.
Si vamos a tener que usar las dos b usquedas, sera conveniente que busquemos
una alternativa que encapsule lo que puede cambiar y mantenga el resto sin
modicaciones. Para lograr esto podramos pasarle a la b usqueda una funcion
que compare el valor central y la clave e indique si el valor que buscamos se
encuentra a la derecha o izquierda.
def mayor(n1, n2):
if n1 > n2:
return True
else:
return False
def menor(n1, n2):
if n1 < n2:
return True
else:
return False
def binaria(cmp, lista, clave):
"""Binaria es una funcion que busca en una lista la clave pasada. Es un requisito
de la busqueda binaria que la lista se encuentre ordenada, pero no si el orden
es ascendente o descendente. Por este motivo es que tambien recibe una funcion
que le indique en que sentido ir.
Si la lista esta ordenada en forma ascendente la funcion que se le pasa tiene
que ser verdadera cuando el primer valor es mayor que la segundo; y falso en
caso contrario.
Si la lista esta ordenada en forma descendente la funcion que se le pasa tiene
que ser verdadera cuando el primer valor es menor que la segundo; y falso en
caso contrario."""
min = 0
max = len(lista) - 1
centro = (min + max) / 2
while (lista[centro] != clave) and (min < max):
if cmp(lista[centro], clave):
max = centro -1
else:
min = centro + 1
centro = (min + max) / 2
if lista[centro] == clave:
return centro
else:
return -1
Entonces, si ahora queremos buscar el n umero 8 en una lista ordenada as-
cendentemente, vamos a tener que pasarle el nombre de la funcion que tiene que
usar para comparar, la lista y la clave.
>>> binaria(mayor, [1,2,3,4,5,6,7,8,9], 8)
33
7
Vemos en el ejemplo anterior que nos da bien la posicion ya que nos retorna
la posicion n umero 7; pero que pasara si en lugar de pasarle la funcion mayor
le pasamos la de menor?.
>>> binaria(menor, [1,2,3,4,5,6,7,8,9], 8)
-1
Como piensa que la lista esta ordenada en forma descendente y 5 va a ser
menor que 8, en la primer iteracion va a descartar la segunda parte de la lista
y se quedara solo con la primera. Por ese motivo es que nunca va a encontrar el
8 en la lista.
Y si ahora buscamos el 123 con la funcion que corresponde?.
>>> binaria(mayor, [1,2,3,4,5,6,7,8,9], 123)
-1
Como deba pasar, si el n umero no se encuentra en la lista, retorna -1.
Y si ahora buscamos algunos valores en una lista ordenada descendentemente,
pasandole la funcion menor?.
>>> binaria(menor, [9,8,7,6,5,4,3,2,1], 8)
1
>>> binaria(menor, [9,8,7,6,5,4,3,2,1], 2)
7
>>> binaria(menor, [9,8,7,6,5,4,3,2,1], 123)
-1
Si los valores estan en la lista nos informa la posicion en que se encuentran,
pero si no existen nos devuelve un -1.
>>> binaria(mayor, [9,8,7,6,5,4,3,2,1], 2)
-1
Al igual que cuando le pas abamos una lista ordenada en forma ascendente y
la funcion menor, si ahora le pasamos una lista ordenada en forma descendente
y la mayor, la b usqueda no va a poder encontrar la clave por mas que exista.
Ahora que probamos la funcion vemos que efectivamente hace lo que debera
hacer, pero, que es ese texto que esta entre """ y para que sirve?. Eso es un
comentario de mas de una lnea llamado docstring y sirve para documentar
las funciones, entre otras cosas.
Pero no es la primera vez que nos topamos con este tipo de documentacion, ya
que antes lo usamos sin saber como estaba hecho o como se llamaba. La forma
de usarlo es a traves de __doc__ y help():
>>> print binaria.__doc__
Binaria es una funcion que busca en una lista la clave pasada. Es un requisito
de la busqueda binaria que la lista se encuentre ordenada, pero no si el orden
es ascendente o descendente. Por este motivo es que tambien recibe una funcion
que le indique en que sentido ir.
Si la lista esta ordenada en forma ascendente la funcion que se le pasa tiene
34
que ser verdadera cuando el primer valor es mayor que la segundo; y falso en
caso contrario.
Si la lista esta ordenada en forma descendente la funcion que se le pasa tiene
que ser verdadera cuando el primer valor es menor que la segundo; y falso en
caso contrario.
>>> help(binaria)
Help on function binaria in module __main__:
binaria(cmp, lista, clave)
Binaria es una funcion que busca en una lista la clave pasada. Es un requisito
de la busqueda binaria que la lista se encuentre ordenada, pero no si el orden
es ascendente o descendente. Por este motivo es que tambien recibe una funcion
que le indique en que sentido ir.
Si la lista esta ordenada en forma ascendente la funcion que se le pasa tiene
que ser verdadera cuando el primer valor es mayor que la segundo; y falso en
caso contrario.
Si la lista esta ordenada en forma descendente la funcion que se le pasa tiene
que ser verdadera cuando el primer valor es menor que la segundo; y falso en
caso contrario.
(END)
4.2. Uso de modulos externos
As como en Pascal usando la clausula Uses y en C el #include, podamos
usar codigo que no perteneca al archivo que estabamos codicando, en Python
podemos hacer lo mismo usando la clausula import y poniendo a continuacion
el nombre del modulo. Por ejemplo, si queremos importar el modulo datetime
6
:
import datetime
Para usarlo simplemente tenemos que poner el nombre del modulo, un punto
y la funcion que queramos usar. En este caso, dentro del modulo datetime vamos
a usar la funcion que se encuentra en date y se llama today().
>>> import datetime
>>> print datetime.date.today()
2009-06-24
>>>
Pero a diferencia de Pascal y C, aca podemos elegir importar una funcion o
algo en particular de ese modulo, en lugar de traerlo todo. Para eso tendramos
que poner en primer lugar la clausula from, luego el nombre del modulo y a
continuacion la clausula import todo lo que queremos importar separada por
comas.
Por ejemplo, del modulo datetime podramos traer las clases
7
date y time.
Despues, para usarlo simplemente lo hacemos llamando lo que importamos sin
el nombre del modulo.
6
El modulo datetime sirve para el manejo de fechas y horas.
7
Por ahora, no presten demasiada atencion al hecho de que sean clases, no vamos a cambiar
al paradigma de Programacion Orientada a Objetos (POO).
35
>>> from datetime import date, time
>>> print date.today()
2009-06-24
>>> print time(1, 23, 32)
01:23:32
>>>
Si nosotros tenemos un archivo llamado ejemplo.py que tiene el siguiente
codigo:
def imprimir(param):
print param
def sumar(n1, n2):
return n1+n2
y queremos importarlo a otro archivo y usarlo:
>>> import ejemplo
>>> ejemplo.imprimir("123")
123
>>> print ejemplo.sumar(2,3)
5
>>>
Como dijimos, tambien podemos importar solo una funcion de ese modulo
y usarla como si estuviera en el nuestro.
>>> from ejemplo import sumar
>>> print sumar(4, 5)
9
>>>
5. Persistencia de datos
Pero todo lo que vimos por el momento se guarda en memoria dinamica, por
lo que al apagar la computadora, o simplemente con cerrar el programa y volver
a abrirlo perdimos todos los datos que nos tenamos. La alternativa para esto
siguen siendo los archivos.
5.1. Uso de archivos
Para poder usar un archivo vamos a tener que hacer los mismos pasos que
siempre, pero de una forma distinta a la de Pascal e igual a la de C. Vamos a
necesitar una variable de tipo archivo, a la cual le vamos a asignar un archivo
fsico y lo vamos a abrir de una forma particular. Una vez que hayamos hecho
todos estos pasos, y si no hubo problema en ninguno de ellos, vamos a poder
leer y, dependiendo del modo en que lo abrimos, escribir en el.
36
5.1.1. Apertura de archivos
Al igual que en C, en Python en el mismo momento que abrimos el archivo, se
lo asignamos a uno fsico y elegimos el modo de apertura, que si no le indicamos
nada, tomara por defecto el de lectura.
El modo de apertura puede ser cualquier combinacion de:
Modo Descripci on
r Lectura: el archivo debe existir. Similar al
reset de Pascal.
w Escritura: no es necesario que el archivo ex-
ista, pero si existe lo sobre escribe. Similar al
rewrite de Pascal.
a Append: Solo agrega al nal y no es necesario
que el archivo exista. Similar al append de Pas-
cal.
b Binario.
+ Permite lectura y escrituras simultaneas.
La primitiva del lenguaje para abrir y asignar un archivo es open, la cual
puede recibir uno o dos parametros. El primero es obligatorio, y corresponde
a la ubicacion relativa o absoluta del archivo fsico. El segundo paramemetro
indica el modo de apertura y es opcional. Si no se lo pasamos asumira que lo
queremos abrir en modo Lectura.
Supongamos que estamos en un escenario en el que solo tenemos un archivo que
se llama f2.txt y queremos trabajar con los archivos f1.txt, f.txt y f3.txt.
>>> file = open("f1.txt")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: f1.txt
>>> file = open("f1.txt", "w")
>>> file2 = open("f2.txt")
>>> file3 = open("f3.txt", "r+w")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: f3.txt
>>> file3 = open("f3.txt", "w+r")
>>>
Podemos ver que cuando intentamos abrir en modo lectura el archivo f1.txt
fallo la aplicacion que dice "IOError: No existe el archivo o directorio: f1.txt".
A continuacion lo intentamos abrir en modo escritura, que, como dijimos antes,
si no existe lo crea; y eso fue lo que paso. El archivo no exista, pero igual
no tuvimos problemas para abrirlo. Aunque recuerden que si el archivo existe
estaramos borrandolo completamente.
Una vez que abrimos el archivo f1.txt, vamos a abrir el archivo f2.txt (el
unico que exista) de igual forma a como habamos abierto el primero para ver
que el problema estaba en la inexistencia de aquel y no en la forma de abrirlo.
Ahora, intentemos abrir en modo lecto-escritura combinando r y w. Si el
archivo no existe, e intentamos primero abrirlo para lectura y despues para
escritura nos va a tirar un error similar al que habamos tenido al abrir f1.txt,
37
por lo que en este caso es conveniente abrirlo primero para escritura y despues
para lectura.
5.1.2. Cierre de archivos
Para cerrar un archivo solo tenemos que indicarselo poniendo la variable
seguida de un punto y la primitiva close(). La unica restriccion es que la
variable sea de tipo archivo, si cerramos un archivo cerrado este sigue cerrado;
y si cerramos uno abierto, el mismo cambia de estado.
>>> type(file2)
<type file>
>>> file2.close()
>>> file2.close()
>>> file2.close()
>>>
5.1.3. Lectura de archivos
Supongamos que tenemos un archivo llamado ejemplo.txt y tiene el sigu-
iente texto:
ejemplo.txt
Python was created in the early 1990s by Guido van Rossum at Stichting
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
as a successor of a language called ABC. Guido remains Pythons
principal author, although it includes many contributions from others.
In 1995, Guido continued his work on Python at the Corporation for
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
in Reston, Virginia where he released several versions of the
software.
In May 2000, Guido and the Python core development team moved to
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
year, the PythonLabs team moved to Digital Creations (now Zope
Corporation, see http://www.zope.com). In 2001, the Python Software
Foundation (PSF, see http://www.python.org/psf/) was formed, a
non-profit organization created specifically to own Python-related
Intellectual Property. Zope Corporation is a sponsoring member of
the PSF.
All Python releases are Open Source (see http://www.opensource.org for
the Open Source Definition). Historically, most, but not all, Python
releases have also been GPL-compatible.
Para leer un archivo podemos usar la primitiva read(), la cual puede recibir
un parametro que indique la cantidad de caracteres a leer. Si no se pasa ese
parametro el interprete leera todo el archivo y lo retornara.
>>> arch = open("ejemplo.txt")
>>> cadena = arch.read(15)
38
>>> # Imprimo los primeros 15 caracteres del archivo.
... print cadena
Python was crea
>>> # Leo otros 7 caracteres y dejo el cursor del archivo en la siguiente posicion.
... cadena = arch.read(7)
>>> print cadena
ted in
>>> # Ahora leo el resto del archivo.
... cadena = arch.read()
>>> print cadena
the early 1990s by Guido van Rossum at Stichting
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
as a successor of a language called ABC. Guido remains Pythons
principal author, although it includes many contributions from others.
In 1995, Guido continued his work on Python at the Corporation for
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
in Reston, Virginia where he released several versions of the
software.
In May 2000, Guido and the Python core development team moved to
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
year, the PythonLabs team moved to Digital Creations (now Zope
Corporation, see http://www.zope.com). In 2001, the Python Software
Foundation (PSF, see http://www.python.org/psf/) was formed, a
non-profit organization created specifically to own Python-related
Intellectual Property. Zope Corporation is a sponsoring member of
the PSF.
All Python releases are Open Source (see http://www.opensource.org for
the Open Source Definition). Historically, most, but not all, Python
releases have also been GPL-compatible.
>>>
La unica condicion que tenemos para usar este metodo es que el archivo lo
hayamos abierto en modo lectura.
>>> arch2 = open("ejemplo2.txt", "w")
>>> arch2.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor
>>> arch3 = open("ejemplo3.txt", "a")
>>> arch3.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor
Otra primitiva que podemos usar es readline(), que al igual que read(),
tambien puede recibir un parametro que indique la cantidad maxima de bytes
39
a leer. Si no se le pasa ning un parametro, lee toda la lnea.
>>> arch = open("ejemplo.txt")
>>> linea = arch.readline()
>>> print linea
Python was created in the early 1990s by Guido van Rossum at Stichting
>>> linea = arch.readline(7)
>>> print linea
Mathema
>>>
Pero no es necesario que leamos de a una sola lnea, sino que tambien pode-
mos leer todas las lneas del archivo y guardarlas en una lista haciendo uso de
la primitiva readlines().
>>> arch = open("ejemplo.txt")
>>> lineas = arch.readlines()
>>> print lineas
[Python was created in the early 1990s by Guido van Rossum at Stichting\n, Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands\n, "as a successor of a language called ABC. Guido remains Pythons\n", principal author, although it includes many contributions from others.\n, \n, In 1995, Guido continued his work on Python at the Corporation for\n, National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)\n, in Reston, Virginia where he released several versions of the\n, software.\n, \n, In May 2000, Guido and the Python core development team moved to\n, BeOpen.com to form the BeOpen PythonLabs team. In October of the same\n, year, the PythonLabs team moved to Digital Creations (now Zope\n, Corporation, see http://www.zope.com). In 2001, the Python Software\n, Foundation (PSF, see http://www.python.org/psf/) was formed, a\n, non-profit organization created specifically to own Python-related\n, Intellectual Property. Zope Corporation is a sponsoring member of\n, the PSF.\n, \n, All Python releases are Open Source (see http://www.opensource.org for\n, the Open Source Definition). Historically, most, but not all, Python\n, releases have also been GPL-compatible.\n]
>>>
Otra forma de leer el archivo por lneas es usando la estructura for y
quedara casi como lo diramos en castellano: "Para cada lnea del archivo:".
Por ejemplo, si queremos imprimir la cantidad de caracteres de cada lnea po-
dramos hacer:
>>> arch = open("ejemplo.txt")
>>> for linea in arch:
... print len(linea)
...
71
69
65
71
1
67
71
62
10
1
65
71
63
69
63
67
67
9
1
71
40
70
40
>>>
Como se puede ver, en el archivo hay lneas que aparentemente no tienen
ning un caracter, y sin embargo, si vemos los n umeros encontramos lneas con
0 caracteres. Eso se debe a que en todas las lneas podemos encontrar siempre
el caracter de n de lnea que se representa por el \n, pero al momento de
imprimirlo no lo vemos.
5.1.4. Escritura de archivos
Para escribir en un archivo podemos usar las las primitivas write(string)
y writelines(lista_strings), que la primera es para escribir una cadena de
caracteres y la segunda para escribir una lista de strings, uno a continuacion del
otro. Es importante destacar que en ning un caso se escribe alg un caracter que
no gure en los strings, como por ejemplo, caracteres de n de lnea.
El uso de writelines es equivalente a recorrer la lista y hacerle un write a
cada elemento.
Pero el costo de escribir algo en el disco es mucho mayor a escribirlo en memoria
por lo que, al igual que en C, se usa un buffer, que no es mas que una porcion
de memoria para ir guardando en forma temporal los datos y cuando alcanzan
un tama no considerable se lo manda a escribir al disco. Otra forma de asegu-
rarse que se haga la escritura es usando la primitiva flush, la cual guarda en el
disco el contenido del buer y lo vaca.
>>> arch2 = open("ejemplo2.txt", "w")
>>> arch2.write("Es la primer cadena")
>>> arch2.write("Seguida de la segunda con un fin de linea\n")
>>> arch2.writelines(["1. Primero de la lista sin fin de lnea. ", "2. Segundo string con fin de lnea.\n", "3. Tercero con/\n.\n", "4. y ultimo."])
>>> arch2.flush()
>>> arch2.close()
>>> arch2 = open("ejemplo2.txt", "r+a")
>>> strfile = arch2.read()
>>> print strfile
Es la primer cadenaSeguida de la segunda con un fin de linea
1. Primero de la lista sin fin de lnea. 2. Segundo string con fin de lnea.
3. Tercero con/
.
4. y ultimo.
>>> arch2.write("Esto lo estoy agregando.\n.")
>>> arch2.writelines("Y estas dos lneas tambien con un \\n al final\n de cada una.\n")
>>> arch2.flush()
>>> arch2 = open("ejemplo2.txt", "r")
>>> print arch2.read()
Es la primer cadenaSeguida de la segunda con un fin de linea
1. Primero de la lista sin fin de lnea. 2. Segundo string con fin de lnea.
3. Tercero con/
.
4. y ultimo.Esto lo estoy agregando.
41
.Y estas dos lneas tambi en con un \n al final
de cada una.
>>>
Otra forma de asegurarse que se escriba lo que hay en el disco es cerrandolo.
5.1.5. Moverse en un archivo
Al igual que en los archivos binarios de Pascal, en Python tambien podemos
saltar a distintas posiciones mediante la primitiva seek(pos) la cual recibe,
como mnimo un parametro que indica la posicion a la que nos queremos mover.
Opcionalmente puede recibir un segundo parametro:
Valor del parametro Signicado
0 La posicion es desde el inicio del archivo y
debe ser mayor o igual a 0
1 La posicion es relativa a la posicion actual;
puede ser positiva o negativa.
2 La posicion es desde el nal del archivo, por
lo que debe ser negativa.
>>> arch = open("ejemplo.txt")
>>> # Voy a la posicion numero 30 del archivo
... arch.seek(30)
>>> print arch.read(7)
y 1990s
>>> # Me muevo 5 posiciones para atras desde mi posicion actual.
... arch.seek(-5,1)
>>> print arch.read(7)
1990s b
>>> # Me muevo a la posicion numero 12, comenzando a contar desde el final.
... arch.seek(-12,2)
>>> print arch.read(10)
compatible
>>>
Y as como podemos movernos en un archivo, tambien podemos averiguar
nuestra posicion usando la primitiva tell().
>>> arch.seek(30)
>>> arch.tell()
30L
>>> arch.seek(-5,1)
>>> arch.tell()
25L
>>> arch.seek(-12,2)
>>> arch.tell()
1132L
>>> print arch.read(10)
42
compatible
>>> arch.tell()
1142L
>>>
5.1.6. Interrogando un archivo
Tambien se le pueden hacer distintas como por ejemplo el nombre, el modo en
que esta abierto, si esta cerrado, entre otros. Usar help() para mas informacion.
>>> arch.name
ejemplo.txt
>>> arch.mode
r
>>> arch.closed
False
6. Anexo I
6.1. Licencia: GPL
Python posee una licencia de codigo abierto, denominada Python Software
Foundation License, que es compatible con la licencia GPL a partir de la version
2.1.1, e incompatible en ciertas versiones anteriores. Esta licencia no obliga a
liberar el codigo fuente al distribuir los archivos binarios
8
.
Para mas informacion pueden tipear license() en el interprete Python.
6.2. Peps (Python Enhancement Proposal o Propuestas
de Mejora de Python)
Las Peps son propuestas para mejorar Python, pero no solo a nivel de nuevas
implementaciones sino tambien de como usarlo.
Por ejemplo, la n umero 8: http://www.python.org/dev/peps/pep-0008/ pro-
pone un estilo de codigo a seguir para los que programen en Python, el cual se
puede respetar o no, pero es una convencion para que sea mas legible el codigo
y cometer menos errores.
La n umero 20 comenta el Zen de Python que vimos antes y la 257 comenta
como hacer buena documentacion para las funciones (docstring).
Por lo que se puede ver en http://www.python.org/dev/peps/, las mismas
estan divididas en las siguientes categoras:
Meta-PEPs (PEPs about PEPs or Processes)
Other Informational PEPs
Accepted PEPs (accepted; may not be implemented yet)
Open PEPs (under consideration)
8
http://www.python.org/psf/license/
43
Finished PEPs (done, implemented in code repository)
Deferred, Abandoned, Withdrawn, and Rejected PEPs
6.3. Donde bajarlo
Si usas linux es probable que lo tengas instalado, y en caso de que esto no
sea as, es probable que la herramienta de gestion de paquetes de tu distribucion
lo tenga disponible.
Si no usas linux, tienen que buscar la version para su sistema operativo en
http : //www.python.org/download/.
6.4. Referencias
http://www.python.org/dev/peps/
http://es.wikipedia.org/wiki/Python
http://www.python.org/
http://diveintopython.org/index.html
http://mundogeek.net/
44

Indice
1. Lenguaje interpretado 1
1.1. Diferencias entre un lenguaje interpretado y uno compilado . . . 1
1.2. Caractersticas de Python . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1. The Zeb of Python . . . . . . . . . . . . . . . . . . . . . . 3
1.3. Estructura de un programa en Python . . . . . . . . . . . . . . . 5
1.4. Interprete Python . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.1. Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . 7
2. Tipos de datos y como manipularlos 8
2.1. Tipos soportados . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.1. Conversion entre tipos . . . . . . . . . . . . . . . . . . . . 13
2.1.2. Algunas funciones utiles para conocer un poco mas lo que
usamos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3. Estructuras de control 21
3.1. Equivalencias de estructuras de control entre Python, Pascal y C 21
3.1.1. if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.1.2. case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.1.3. for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.1.4. while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.1.5. repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4. Programacion modular 28
4.1. Procedimientos y funciones . . . . . . . . . . . . . . . . . . . . . 28
4.2. Uso de modulos externos . . . . . . . . . . . . . . . . . . . . . . . 35
5. Persistencia de datos 36
5.1. Uso de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.1.1. Apertura de archivos . . . . . . . . . . . . . . . . . . . . . 37
5.1.2. Cierre de archivos . . . . . . . . . . . . . . . . . . . . . . 38
5.1.3. Lectura de archivos . . . . . . . . . . . . . . . . . . . . . . 38
5.1.4. Escritura de archivos . . . . . . . . . . . . . . . . . . . . . 41
5.1.5. Moverse en un archivo . . . . . . . . . . . . . . . . . . . . 42
5.1.6. Interrogando un archivo . . . . . . . . . . . . . . . . . . . 43
6. Anexo I 43
6.1. Licencia: GPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2. Peps (Python Enhancement Proposal o Propuestas de Mejora de
Python) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.3. Donde bajarlo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
6.4. Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
45

You might also like