Está en la página 1de 45

Introducción a Python

Gonzalo Soriano
gsoriano@f i.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 (también llamado
lenguaje de máquina) por lo que al compilar un programa lo que hacemos es
traducir ese código 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 código 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 máquina donde se lo compiló, éste
puede correr sin necesidad del compilador.
Velocidad de ejecución: Al traducir el código 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 código lo optimice mejorando su
velocidad de ejecución.
Como todo, también 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 código 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 modificación que se le haga al progra-
ma puede llevar a recompilar todo el programa, o por lo menos una gran
parte de él. Si estamos desarrollando un programa de gran envergadu-
ra y estamos en una etapa en la que se hacen y prueban modificaciones
constantemente podemos perder mucho tiempo recompilando todo hasta
encontrar la versión final.

1
Una alternativa a usar un lenguaje compilado, es usar un lenguaje interpre-
tado. Las computadoras siguen entendiendo un único lenguaje, pero ahora lo
que se hace es usar un lenguaje compilado para crear un interprete (también
conocido como máquina virtual ), el cual estará entre nuestro código fuente y
la computadora cumpliendo la función de todo interprete: traducir solo lo que
necesita de un lenguaje a otro. Acá 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 porción del código nunca sea traducida al lenguaje máquina.
Como contra, al traducir en el momento y no guardar esas traducciones, puede
suceder que una porción del código 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 deberı́a modificarse en una sola lı́nea y
seguir funcionando perfectamente.
Agilidad en el desarrollo: Como no tenemos que compilar el programa
para hacer pruebas (solo tenemos que correrlo sobre el intérprete) es más
rápido para hacer pruebas y continuar con el desarrollo o buscar el error.
Este tipo de lenguajes tampoco es perfecto y, por supuesto, también 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 ejecución: Como toda instrucción tiene que pasar por el
interpreté, para que éste la traduzca y luego se ejecute es, un poco, más
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. Caracterı́sticas de Python


Algunas de las caracterı́sticas que podemos encontrar en Python son:

Agilidad en el desarrollo I: Es rápido para probar y continuar desarrol-


lando gracias a que cuenta con un interprete que va ejecutando el código
a medida que lo escribimos en él. Es muy cómodo para probar pequeñas
porciones de código.

2
Agilidad en el desarrollo II: rápido para programar la simplicidad del
lenguaje y por las herramientas que contamos.

Muy fácil de entender lo que hace el programa, ya que el código es limpio


y elegante.
Es multiplataforma, por lo que el mismo código la mayorı́a de las veces se
puede ejecutar en distintas computadoras y con distintos sistemas opera-
tivos sin modificaciones.

Cuenta con una gran cantidad de módulos con muchas funcionalidades


directamente en el standard.
Es un lenguaje fuertemente tipado pero de asignación dinámica. 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ño.

1.2.1. The Zeb of Python


Desde la versión 2.1.2 de Python, si tratamos de importar el módulo ”this”nos
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 aren’t 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 you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let’s do more of those!

La traducción serı́a 1 :

1 http://es.wikipedia.org/wiki/Python

3
1. Bello es mejor que feo.
2. Explı́cito es mejor que implı́cito.

3. Simple es mejor que complejo.


4. Complejo es mejor que complicado.
5. Plano es mejor que anidado.
2
6. Ralo es mejor que denso.
7. La legibilidad cuenta.
8. Los casos especiales no son tan especiales como para quebrantar las reglas.
9. Aunque lo práctico gana a la pureza.

10. Los errores nunca deberı́an dejarse pasar silenciosamente.


11. A menos que hayan sido silenciados explı́citamente.
12. Frente a la ambigüedad, rechaza la tentación de adivinar.
13. Deberı́a haber una -y preferiblemente sólo una- manera obvia de hacerlo.

14. Aunque esa manera puede no ser obvia al principio a menos que usted sea
Holandés
15. Ahora es mejor que nunca.
16. Aunque nunca es a menudo mejor que ya.

17. Si la implementación es difı́cil de explicar, es una mala idea.


18. Si la implementación es fácil de explicar, puede que sea una buena idea.
19. Los espacios de nombres (namespaces) son una gran idea ¡Hagamos más
de esas cosas!

Si bien todas son buenas prácticas de programación, 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 implementación es difı́cil de explicar, es una mala idea.


2 Me gusta más: 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 función en particular. Simplemente con escribir
un par de lı́neas de código ya podrı́amos decir que tenemos un programa en
Python.
Lo que es importante destacar es la forma de identificar los distintos bloques de
código. En Pascal se definı́a un bloque de código usando las palabras reservadas
Begin y End; en C/C++ se define mediante el uso de las llaves ({ y }). Sin em-
bargo, en Python, se utiliza la indentación; es decir, la cantidad de espacios/tabs
que hay entre el comienzo de la lı́nea y el primer carácter distinto a ellos.

1.4. Interprete Python


El interprete de Python es una herramienta muy útil al momento de desar-
rollar, ya que se puede ir probando pequeñas porciones del código sin necesidad
de hacer todo el programa. Lo único 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 comenzará con >>>, en el cual
podremos escribir código y automáticamente se irá interpretando.
Cuando usamos una estructura selectiva o de repetición generalmente vamos a
tener que escribir más de una lı́nea, por lo que el interprete no va a ejecutar ese
código hasta que se lo indiquemos dejando una lı́nea en blanco, es decir, con solo
un Enter. Para indicarnos que todavı́a 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 código se va a interpretar una vez que lo invoquemos, y no al terminar de
definirlo.

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úmeros, 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 lı́nea en blanco para que el interprete ejecute
nuestro código.

$ 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úmero 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 también 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-
drı́amos 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 tendrı́amos que hacer:

$python ejemplo.py

Y la salida serı́a:

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 función 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 código que se entienda ayuda a


encontrarlos.
2. Todos los programas sufren modificaciones a lo largo de su vida, al menos
todos aquellos que tienen éxito.
Por cualquiera de estas razones es conveniente escribir un código claro, legible
y ayudarlo con comentarios para facilitar estas tareas. Lo cual no significa que
a partir de ahora vayan a escribir más lı́neas de comentarios que de código, ya
que también hay que saber que escribir.
Al momento de hacer un comentario hay que pensar en cuanta información nue-
va estas aportando, o cuanto más legible queda el código para quien lo tenga
que leer y mantener.

La forma de hacer comentarios en Python es anteponiendo el #, de esa for-


ma, desde ese carácter hasta el fin de la lı́nea se obviaran todos los caracteres
al momento de ejecutar el código. Por ejemplo, si tomamos el código 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 también es un comentario
# Y esto.

El ejemplo anterior es muy básico, 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
código, ya que lo único que hacen es decir que hace el programa lı́nea por
lı́nea sin aportar nada nuevo. Si los comentarios son solo una traducción del
lenguaje que están usando a su lenguaje nativo, dejan de ser útiles y para colmo
agregamos algo más que hay que mantener. Si el código cambia de forma que
los comentarios queden desactualizados (cosa que es muy común que pase con
este tipo de comentarios) hay que mantenerlos para que no confundan a quien
lo lee.
Un comentario es útil cuando indicamos algo que no es evidente. Por ejemplo,
si vemos el siguiente código es difı́cil entender lo que hace esa lı́nea.
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 lı́nea le agregamos un comentario, podemos darnos cuenta


fácilmente 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-
terı́stica de tipado dinámico. 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 flotante. Y es tipado dinámico 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 lı́nea siguiente,
a esa variable asignarle un número.
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 T rue y F alse.
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 final 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 flotante (f loat)
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 modificar.
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 Hash0 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úmeros enteros, números
complejos, números reales, booleanos y tuplas; pero no listas ni diccionarios ya
que son mutables. Además, 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: u’otro 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. Conversión entre tipos


Para convertir a un número entero se puede usar la función int(n), a la
cual se le puede pasar un string o un float, pero no un string que sea un float.
>>> 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 función también se le puede pasar un número 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, también podemos pasar a números
flotantes, pero no tenemos tantas alternativas como antes. Para eso podemos
usar la función f loat(string) que recibe una cadena de caracteres y retorna un
float.

>>> 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
>>>
También se le puede pasar un número entero y lo convierte a flotante:
>>> float(12)
12.0
Para convertir cualquier variable a string podemos usar la función str() que
recibe cualquier cosa y hace su mejor intento para convertirla. A diferencia del
resto, esta función nunca va a fallar por no saber cómo convertir algo. Puede
pasar que con algún tipo en particular no nos devuelva el resultado que quere-
mos, pero seguro que nos va a devolver una representación 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 después pasar todos los
parámetros juntos. Al igual que en C, cuando marcamos la posición donde quer-
emos que se ingrese algún valor, también vamos a tener que indicar el tipo de
ese parámetro; y ellos pueden ser:

14
Indicador Tipo:
%c Solo un carácter.
%s Cadena de caracteres.
%d o %i o %u 0 %ld 0 %lu Entero con signo.
%nd Entero con signo ocupando n3 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 notación cientı́fica.
%.ne Float o double, con notación cientı́fica, con solo n decimales.
%g Coma flotante, usando la notación 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’
>>>
Además se pueden mezclar con los siguientes caracteres:

15
Carácter Descripción
\n Carácter fin de lı́nea.
\r Carácter retorno del carro.
\t Carácter tabulador horizontal.
\v Carácter tabulador vertical.
\a Timbre.
\\ Barra invertida.
\" Comillas.
\’ Apóstrofe.

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 función join() de la siguiente forma:

>>> " ".join(("Algoritmos", "y", "Programación", "I"))


’Algoritmos y Programación I’
>>> "".join(["Algoritmos", "y", "Programación", "I"])
’AlgoritmosyProgramaciónI’
>>> " ".join(["Algoritmos", "y", "Programación", "I"])
’Algoritmos y Programación I’
>>>> "##separador##".join(["Algoritmos", "y", "Programación", "I"])
’Algoritmos##separador##y##separador##Programación##separador##I’

Y como sucede generalmente, si hay una función que va en un sentido existe


otra que va en el sentido inverso. Para parsear un string y obtener una lista
podemos usar la función split. Por defecto el separador es el espacio, por lo que
si le pasamos una oración, nos la separará 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’]
También se puede obtener partes de un string indicando su posición respecto
del inicio o el rango que se desea obtener. Para indicar un rango se pone primero
la posición del comienzo, después un separador que será el : y por último la
posición del final. Si no se le pasa la posición donde comienza el rango, asume
que ese valor es 0; y si la posición que no se le pasa es la del final, asume que es
hasta el final 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 posición desde el inicio de la cadena de carac-
teres, también podemos indicar la posición respecto del último carácter:

Cadena de caracteres: H o l a m u n d o
Posición desde el inicio: 0 1 2 3 4 5 6 7 8 9
Posición desde el final: -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, también se le pueden especificar 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 función range([piso], techo); que puede recibir uno o dos parámetros. Si se
le pasa un solo parámetro la función devuelve una lista que tendrá todos los
números que sean iguales o mayores a 0 y menores a ese número.

>>> range(3)
[0, 1, 2]
>>> range(-1)
[]

En cambio, si se le pasan dos parámetros nos va a devolver una lista que


tendrá todos los números 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 útiles 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 través
de la función keys().
>>> {1:"uno", 2:"dos", 3:"tres"}.keys()
[1, 2, 3]
Y si podemos obtener sus claves, también podemos obtener los valores asociados
a esas claves. Para esto tendremos que hacer uso de la función values()
>>> {1:"uno", 2:"dos", 3:"tres"}.values()
[’uno’, ’dos’, ’tres’]

2.1.2. Algunas funciones útiles para conocer un poco más lo que


usamos.
Otra herramienta de Python muy útil es la de poder averiguar información
sobre lo que usamos en tiempo de ejecución, aunque también para eso podemos
usar el interprete.
Las funciones que vamos a usar son dir(), __doc__ y help().
La función dir() nos da información de como manipular ese objeto. Por ejemplo,
si a esta función 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 función __doc__ nos da información de como usar una función en particular.
Para poder conseguir esa información 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 más la función find() de un string
podrı́amos 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 último, nos queda la función help() que al invocarla nos muestra las
funciones para manipular esa variable con una descripción 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 isn’t 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 también existen estructuras para
controlar el flujo del código 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 ejecución con un Begin ... end o unas { ... }
sino que se utiliza la indentación.

Pascal
if (condición) then
acción;
o

21
if (condición) then
begin
acción1;
acción2;
...
acciónN;
end;
C

if (condición)
acción;

o
if (condición)
{
acción1;
acción2;
...
acciónN;
}
Python
if (condición):
acción1;
acción2;
...
acciónN;
A diferencia de Pascal y C, en Python no hay diferencia entre poner una sola
acción o varias. Además, es obligatorio que las acciones estén todas equidistantes
del comienzo de la lı́nea 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 más 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 mayorı́a de los lenguajes, la estructura de selección if no solo nos


da la posibilidad de elegir que código ejecutar si una condición es verdadera,
sino que también podemos elegir otra porción de código para el caso de que la
condición sea falsa.

if a > b:
print "a es mayor que b"
else:
print "b es mayor que a"

Muchas veces si la condición es falsa queremos evaluar otras condiciones, por


lo que ”anidamos” este tipo de estructuras poniendo if 0 s en los else0 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, más 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, también 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 tenı́amos que recorrerla toda (o por
lo menos hasta encontrarlo) y fijarnos uno por uno si es lo que buscábamos. 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 asignará 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 serı́an el case en Pascal o el switch
en C y es porque no se lo usa tanto. Además, podemos usar los if anidados para
obtener una estructura aún más potente que un simple discriminador de valores
de una única 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 dirı́a, pero muy limitada:

for variable_iteracion:=valor_inicial to valor_final do


begin

24
accion1;
acción2;
...
accionN;
end;

Por otro lado, en C esta misma estructura es mucho más potente, pero a
costa de sacrificar un poco de legibilidad:

for (condición inicial; condición de corte; modificación de la variable)


{
accion1;
accion2;
...
accionN;
}

Por lo que Python adoptó una tercer forma tratando capturar lo mejor de
cada una de ellas; siempre priorizando la claridad del código.

for elemento in lista:


accion1
acción2
...
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 más fácil.

>>> 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 qué pasa si quiero hacer un f or para que simplemente muestre los


primeros 50 enteros no negativos, o los números del 20 al 30?. La respuesta
esta unas cuantas hojas antes: range().
Para imprimir los primeros 50 números enteros no negativos:

for i in range(50):
print i
Para imprimir los números que van del 20 al 30:

25
for i in range(20, 31):
print i

Recordemos que cuando invocamos la función 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 último).

List comprehensions:

List comprehensions o la comprensión de listas es una estructura para construir


una lista a partir de los elementos de otra. A esos elementos podemos aplicarles
una función que me devuelva algún elemento, como multiplicarlos por 2, y/o
filtrarlos con un if para que solo pasen los que cumplen con alguna condición
en particular.
Por ejemplo, si queremos una lista que tenga el cuadrado de los primeros 16
números 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 también podrı́amos 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 último, vamos a ver como podrı́amos 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) = (02 + 12 , 02 + 32 , 22 + 12 , 22 + 12 , 22 + 32 , 42 + 12 , 42 + 32 )

El uso de list comprehensions puede ser muy útil (no en los ejemplos que
vimos), pero tengan en cuenta que no siempre el código queda más legible y
entendible para el próximo que lo tenga que leer.

26
3.1.4. while
La estructura que conserva más similitudes a las vistas en Pascal o C es el
while.

while <condición>:
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 último 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 número: "))


Ingrese un número: 5
>>> while 1 < num < 10:
... num = int(raw_input("Ingrese un número: "))
...
Ingrese un número: 7
Ingrese un número: 4

27
Ingrese un número: 9
Ingrese un número: 2
Ingrese un número: 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ón 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 código sea legible.
En Python no existen los procedimientos: son todas funciones. Incluso, aunque
nosotros no devolvamos ningún valor, Python lo hará 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 más de esa función; sin importar si esta
dentro de un ciclo o todavı́a no hayamos hecho nada.
La definición de una función comienza usando la palabra reservada def, y con-
tinua dejando un espacio, poniendo el nombre de la función4 , los parámetros
entre paréntesis5 y un dos puntos para terminar la lı́nea. En las lı́neas que le
siguen va el código de la función, que, al igual que para las estructuras de con-
trol, la forma en que se indica el bloque de código que se tiene que ejecutar es
haciendo uso de la indentación.

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 función que calcula el factorial de un
número harı́amos 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
función y el resultado podemos asignárselo a una variable o no.
4 Tiene que cumplir las mismas reglas para las variables, puede empezar con cualquier letra
y el y después le puede seguir cualquier carácter alfanumérico más el .
5 Los paréntesis son obligatorios por más que no se pasen parámetros

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 podrı́amos hacer:

def factorial_rec(n):
if n == 0:
return 1
else:
return n*factorial_rec(n-1)

# Esta lı́nea ya esta fuera de la función y pertenece al bloque principal.


print factorial_rec(5)

Si ahora quisieramos hacer una función que haga la búsqueda binaria sobre
una lista de enteros podrı́amos 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 pasará si ahora queremos hacer una búsqueda binaria sobre una lista
de strings?.

>>> binaria(["Algoritmos", "Programación", "Y"], "Y")


2
>>> binaria(["Algoritmos", "Programación", "Y"], "esta no esta")
-1

Como se puede ver en los ejemplos anteriores, en ningún momento pusimos


el tipo de los parámetros que recibe la función 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
definir valores por defecto para los parámetros de una función. Es decir, si no se
le pasa un valor, ese parámetro toma el valor que definió el programador en el
momento que escribió el código. 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 función reciba algún otro parámetro después de él también debe tener un
valor por defecto. Es decir, los parámetros que tienen valores por defecto solo
pueden ocupar las últimas posiciones.

>>> def imprimir_parametros(param1, param2, param3=5, param4="es el cuarto parametro", par


... 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 parámet-
ros hasta el que nosotros que tome un valor distinto del default, podemos indi-
carlo igualando el nombre del parámetro 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 recién, ni siquiera es necesario pasarle
los parámetros 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ún valor, pero
vemos en imprimir_parametros que en ningún momento se hace un return;
entonces era mentira lo que habı́amos dicho?. Obviamente, no. Pero entonces,
¿qué 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
>>>

También podrı́amos hacer un procedimiento que pida el ingreso de algún


dato, verifique que se encuentre algunos valores posibles y nos devuelva la opción
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 válidas
Seguro que quiere salir?.g
Error. Las opciones válidas son: S y N.
Seguro que quiere salir?.s
Error. Las opciones válidas son: S y N.
Seguro que quiere salir?.S
>>> print opcion
S
>>> def Menu():
... print "1. Opción 1"
... print "2. Opción 2"
... print "3. Opción 3"
... confirmar("", ["1", "2", ""3], "Error!!!!, Las opciones válidas son: " + str(range
...
>>> Menu()
1. Opción 1
2. Opción 2
3. Opción 3
g
Error!!!!, Las opciones válidas son: [1, 2, 3]
s
Error!!!!, Las opciones válidas son: [1, 2, 3]
5

31
Error!!!!, Las opciones válidas son: [1, 2, 3]
1
>>>

Una cosa que puede ser muy útil es asignarle una función a una variable,
ya que también existe el tipo de dato función. 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 último el nombre de la función.

>>> 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-


ción a una variable, después usar esa variable como si llamáramos a la misma
función.
La utilidad de esta funcionalidad no es usar la misma función con otro nombre
para confundir aún más a quien tenga que leer el código, sino, poder elegir en
tiempo de ejecución que función invocar. Por ejemplo, si queremos hacer una
función que haga la búsqueda binaria en una lista ordenada en forma ascendente
podrı́amos usar la función 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úsqueda sobre una lista que
esta ordenada en forma descendente, entonces ya no nos servirı́a nada de lo que
tenemos y tendrı́amos que copiar el mismo código cambiando solamente el signo

32
mayor por un menor y tendrı́amos dos funciones casi iguales que solo diferirı́an
en un solo carácter.
Si vamos a tener que usar las dos búsquedas, serı́a conveniente que busquemos
una alternativa que encapsule lo que puede cambiar y mantenga el resto sin
modificaciones. Para lograr esto podrı́amos pasarle a la búsqueda una función
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 función que busca en una lista la clave pasada. Es un requisito
de la búsqueda binaria que la lista se encuentre ordenada, pero no si el orden
es ascendente o descendente. Por este motivo es que también recibe una función
que le indique en que sentido ir.
Si la lista esta ordenada en forma ascendente la función 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 función 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úmero 8 en una lista ordenada as-
cendentemente, vamos a tener que pasarle el nombre de la función 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 posición ya que nos retorna
la posición número 7; pero que pasará si en lugar de pasarle la función 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 iteración va a descartar la segunda parte de la lista
y se quedará 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 función que corresponde?.

>>> binaria(mayor, [1,2,3,4,5,6,7,8,9], 123)


-1

Como debı́a pasar, si el número no se encuentra en la lista, retorna -1.


Y si ahora buscamos algunos valores en una lista ordenada descendentemente,
pasándole la función 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 están en la lista nos informa la posición 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ábamos una lista ordenada en forma ascendente y


la función menor, si ahora le pasamos una lista ordenada en forma descendente
y la mayor, la búsqueda no va a poder encontrar la clave por más que exista.
Ahora que probamos la función vemos que efectivamente hace lo que deberı́a
hacer, pero, ¿qué es ese texto que esta entre """ y para qué sirve?. Eso es un
comentario de más de una lı́nea llamado docstring y sirve para documentar
las funciones, entre otras cosas.
Pero no es la primera vez que nos topamos con este tipo de documentación, ya
que antes lo usamos sin saber como estaba hecho o como se llamaba. La forma
de usarlo es a través de __doc__ y help():
>>> print binaria.__doc__
Binaria es una función que busca en una lista la clave pasada. Es un requisito
de la búsqueda binaria que la lista se encuentre ordenada, pero no si el orden
es ascendente o descendente. Por este motivo es que también recibe una función
que le indique en que sentido ir.
Si la lista esta ordenada en forma ascendente la función 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 función 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 función que busca en una lista la clave pasada. Es un requisito
de la búsqueda binaria que la lista se encuentre ordenada, pero no si el orden
es ascendente o descendente. Por este motivo es que también recibe una función
que le indique en que sentido ir.
Si la lista esta ordenada en forma ascendente la función 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 función 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 módulos externos


Ası́ como en Pascal usando la cláusula U ses y en C el #include, podı́amos
usar código que no pertenecı́a al archivo que estábamos codificando, en Python
podemos hacer lo mismo usando la cláusula import y poniendo a continuación
el nombre del módulo. Por ejemplo, si queremos importar el módulo datetime 6 :

import datetime

Para usarlo simplemente tenemos que poner el nombre del módulo, un punto
y la función que queramos usar. En este caso, dentro del módulo datetime vamos
a usar la función 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, acá podemos elegir importar una función o


algo en particular de ese módulo, en lugar de traerlo todo. Para eso tendrı́amos
que poner en primer lugar la cláusula from, luego el nombre del módulo y a
continuación la cláusula import todo lo que queremos importar separada por
comas.
Por ejemplo, del módulo datetime podrı́amos traer las clases7 date y time.
Después, para usarlo simplemente lo hacemos llamando lo que importamos sin
el nombre del módulo.

6 Elmódulo datetime sirve para el manejo de fechas y horas.


7 Porahora, no presten demasiada atención al hecho de que sean clases, no vamos a cambiar
al paradigma de Programación 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


código:

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, también podemos importar solo una función de ese módulo
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 dinámica, por
lo que al apagar la computadora, o simplemente con cerrar el programa y volver
a abrirlo perdimos todos los datos que nos tenı́amos. 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
fı́sico 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 él.

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 fı́sico y elegimos el modo de apertura, que si no le indicamos
nada, tomará por defecto el de lectura.
El modo de apertura puede ser cualquier combinación de:
Modo Descripción
’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 final 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 parámetros. El primero es obligatorio, y corresponde
a la ubicación relativa o absoluta del archivo fı́sico. El segundo parámemetro
indica el modo de apertura y es opcional. Si no se lo pasamos asumirá 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
falló la aplicación que dice "IOError: No existe el archivo o directorio: f1.txt".
A continuación lo intentamos abrir en modo escritura, que, como dijimos antes,
si no existe lo crea; y eso fue lo que pasó. El archivo no existı́a, pero igual
no tuvimos problemas para abrirlo. Aunque recuerden que si el archivo existe
estarı́amos borrándolo completamente.
Una vez que abrimos el archivo f1.txt, vamos a abrir el archivo f2.txt (el
único que existı́a) de igual forma a como habı́amos 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 después para
escritura nos va a tirar un error similar al que habı́amos tenido al abrir f1.txt,

37
por lo que en este caso es conveniente abrirlo primero para escritura y después
para lectura.

5.1.2. Cierre de archivos


Para cerrar un archivo solo tenemos que indicárselo poniendo la variable
seguida de un punto y la primitiva close(). La única restricción 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 Python’s
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 parámetro que indique la cantidad de caracteres a leer. Si no se pasa ese
parámetro el interprete leerá todo el archivo y lo retornará.

>>> 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 posición.
... 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 Python’s
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 única condición que tenemos para usar este método 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(),
también puede recibir un parámetro que indique la cantidad máxima de bytes

39
a leer. Si no se le pasa ningún parámetro, lee toda la lı́nea.

>>> 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 lı́nea, sino que también pode-
mos leer todas las lı́neas 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
>>>

Otra forma de leer el archivo por lı́neas es usando la estructura for y


quedarı́a casi como lo dirı́amos en castellano: "Para cada lı́nea del archivo:".
Por ejemplo, si queremos imprimir la cantidad de caracteres de cada lı́nea po-
drı́amos 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 lı́neas que aparentemente no tienen
ningún carácter, y sin embargo, si vemos los números encontramos lı́neas con
0 caracteres. Eso se debe a que en todas las lı́neas podemos encontrar siempre
el carácter de fin de lı́nea 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 continuación del
otro. Es importante destacar que en ningún caso se escribe algún carácter que
no figure en los strings, como por ejemplo, caracteres de fin de lı́nea.
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 más que una porción
de memoria para ir guardando en forma temporal los datos y cuando alcanzan
un tamaño 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 buffer y lo vacı́a.

>>> 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 lı́nea. ", "2. Segundo string con
>>> 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 lı́nea. 2. Segundo string con fin de lı́nea.
3. Tercero con/
.
4. y último.
>>> arch2.write("Esto lo estoy agregando.\n.")
>>> arch2.writelines("Y estas dos lı́neas también 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 lı́nea. 2. Segundo string con fin de lı́nea.
3. Tercero con/
.
4. y último.Esto lo estoy agregando.

41
.Y estas dos lı́neas también con un \n al final
de cada una.

>>>

Otra forma de asegurarse que se escriba lo que hay en el disco es cerrándolo.

5.1.5. Moverse en un archivo


Al igual que en los archivos binarios de P ascal, en P ython también podemos
saltar a distintas posiciones mediante la primitiva seek(pos) la cual recibe,
como mı́nimo un parámetro que indica la posición a la que nos queremos mover.
Opcionalmente puede recibir un segundo parámetro:

Valor del parámetro Significado


0 La posición es desde el inicio del archivo y
debe ser mayor o igual a 0
1 La posición es relativa a la posición actual;
puede ser positiva o negativa.
2 La posición es desde el final del archivo, por
lo que debe ser negativa.

>>> arch = open("ejemplo.txt")


>>> # Voy a la posición número 30 del archivo
... arch.seek(30)
>>> print arch.read(7)
y 1990s
>>> # Me muevo 5 posiciones para atrás desde mi posición actual.
... arch.seek(-5,1)
>>> print arch.read(7)
1990s b
>>> # Me muevo a la posición número 12, comenzando a contar desde el final.
... arch.seek(-12,2)
>>> print arch.read(10)
compatible
>>>

Y ası́ como podemos movernos en un archivo, también podemos averiguar


nuestra posición 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


También se le pueden hacer distintas como por ejemplo el nombre, el modo en
que esta abierto, si esta cerrado, entre otros. Usar help() para más información.

>>> arch.name
’ejemplo.txt’
>>> arch.mode
’r’
>>> arch.closed
False

6. Anexo I
6.1. Licencia: GPL
Python posee una licencia de código abierto, denominada Python Software
Foundation License, que es compatible con la licencia GPL a partir de la versión
2.1.1, e incompatible en ciertas versiones anteriores. Esta licencia no obliga a
liberar el código fuente al distribuir los archivos binarios8 .
Para más información pueden tipear license() en el interprete Python.

6.2. Peps (Python Enhancement Proposal o Propuestas


de Mejora de Python)
Las P eps son propuestas para mejorar Python, pero no solo a nivel de nuevas
implementaciones sino también de como usarlo.
Por ejemplo, la número 8: http://www.python.org/dev/peps/pep-0008/ pro-
pone un estilo de código a seguir para los que programen en Python, el cual se
puede respetar o no, pero es una convención para que sea más legible el código
y cometer menos errores.
La número 20 comenta el Zen de Python que vimos antes y la 257 comenta
como hacer buena documentación para las funciones (docstring).
Por lo que se puede ver en http://www.python.org/dev/peps/, las mismas
están divididas en las siguientes categorı́as:

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 gestión de paquetes de tu distribución
lo tenga disponible.
Si no usas linux, tienen que buscar la versión 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
Índice
1. Lenguaje interpretado 1
1.1. Diferencias entre un lenguaje interpretado y uno compilado . . . 1
1.2. Caracterı́sticas 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. Conversión entre tipos . . . . . . . . . . . . . . . . . . . . 13
2.1.2. Algunas funciones útiles para conocer un poco más 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. Programación modular 28
4.1. Procedimientos y funciones . . . . . . . . . . . . . . . . . . . . . 28
4.2. Uso de módulos 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

También podría gustarte