Introducción a Python

Mariano Rivera

version Agosto 2018

¿BigData + Deep Learning acaso es Compatible con un Lenguaje Interpretado?

Primer programa en Python: Programa que imprime “hola mundo”

Instalar en la computadora la distribución de python (preferentemente versión 3.x).

Si el interprete de python no esta en el $PATH, buscarlo con el comando Unix/Linux:

$which python

/Library/Frameworks/Python.framework/Versions/2.7/bin/python

Revisar que versión de python se tiene instalada

$python --version

Python 2.7.13

el comando python esta asociado con la versión 2.7.x, y no la 3.x que es la estoy recomendando!

Debo buscar python3!

$which python

/Users/marianoriverameraz/anaconda/bin/python3

Crear un archivo de texto con su editor de preferencia llamado hola.py con el contenido de la siguiente línea #1 y el path a mi instalción de pyhton , luego una línea abajo el comando print y salvarlo

#!/Users/marianoriverameraz/anaconda/bin/python3

print(“hola mundo!”)

Probablemente requiramos cambiar los permisos para poder ejecutar hola.py con

invocar la línea de comando:

python hola.py

en el directorio donde esta localizado el archivo hola.py. Eso es todo.

Invocando al Interprete Python directamente

En la línea de comando

$ python3

>>>>>>

Los caracteres >>>>>> son el prompt del interprete de python, aqui podemos dar los comandos de python que gustemos. Por ejemplo:

>>>>>> print(“hola mundo”

hola mundo

>>>>>> 5+8

13

>>>>>> "hola " + “mundo”

‘hola mundo’

Esta en una forma muy cómoda de hacer procesar datos: en forma interactiva.

De hecho existe un interprete especial interactivo llamado ipython que vienen con la distribución

Pero en mas popular son la notebooks de jupyther lab que se encuentra en versión alpha. para instalarlo ver

http://veekaybee.github.io/jupyter-lab/

Tipos Básicos Numéricos

Boleans: bool, bool8, bool

Interos: byte, short, int8, int16, int 32, int64, …

Sin-signo integers: ubyte, ushort, uint8, uint16, uint 32, uint64, …

Punto flotante: single, double, float16, float32, float64, float96, float128

Flotantes complejos: csingle, complex64, complex128, complex192, complex256

Operadores numéricos (strings)

++ Suma (concatena strings)

- Resta

\ast Multiplicación (repite strigs)

// División

//// División entera

** Potencia

%\% Módulo

Estos operadores se pueden combinar con el igual (=) hacer un operador que actua sobre una misma variable. Por ejemplo, en vez de hacer:

x=x+5,y=y%2x = x+5, y = y\%2

se puede escribie

x+=5,y%=2x+=5, y\%=2

# Este es un comentario

x = 3 # x es una variable, no requiere ser declarada, su tipo se define automaticamente al momento de ser inicializada
x # esta linea imprime el valor de la variable
3
print(x) # al igual que llamar a print
3
y = 5
x
y # solo se imprime la ultima variable
5
x+y
8
type(x) # imprime el tipo de la variable x
int
print(type(x))
print(x/y)
print(type(x/y))  # se hace el "cast", cambio de tipo automaticamente
z = x/y
print(y*z)
print(int(z*y)) # cast explícito
<class 'int'>
0.6
<class 'float'>
3.0
3
# potencia
print(x**2)
9

Nota: Python ( a diferencia de muchos lenguajes con C) no tienen operadores de Incremento y Decremento unarios : ++ –

Nota: Tiene incrementar y decremetar:

print(x)
x+=2
print(x,y,z, z**x)
3
5 5 0.6 0.07775999999999998

Operadores Lógicos (de comparación)

==== ¿es igual a?

!=!= ¿es diferenta a?

<,>< \, , > ¿es menor a ? , ¿es mayor a?

<=,>=<=\, , >= ¿es menor o igual a? , ¿es mayor o igual?

Tipo Boleano (True, False) y Operadores Logicos

x, y = True, False           # asignación múltiple en una misma línea
print("x, y = ", x, y)       # el print imprime la secuencia de arcumentos
print("x*y = ", x * y)       # producto
print(x and y)               # operador and logico
print("x or y = ",  x or y)  # operador or logico
print("x xor y = ", x != y)  # operador xor logico  (efectivamente, es cierto ssi x y son distintos!)
print("not x = ", not x)     # operador xor logico  (efectivamente, es cierto ssi x y son distintos!)
x, y =  True False
x*y =  0
False
x or y =  True
x xor y =  True
not x =  False

Strings

hola = "hola"
epc = ''' '''    # cadena con un carecter, el espacio
mundo = 'mundo'  # es indistinto usar cadenas con  dobles comillas o sencillas

s = hola + epc + mundo  # concatenando cadenas
print(s)
print(len(s))   # imprime el calculo de la longitud de una cadena
hola mundo
10
print(s.title())         # Formato de Titulo
print(s.capitalize())    # Primera en mayuscula
print(s.rjust(20))       # Justifica a la derecha, asumiendo ancho de 20
print(s.center(20))      # centra asumiendo ancho de 20, llena con espacio
print(len(s.rjust(20)))  # imprime el acho de la cadena resultante contardo el texto en el ancho de 20
print(s.replace('mun', 'ru'))  # sustituye todas las instancias de una subcadena por otra
print((' '+s))
print((' '+s).strip())   # quita espacios al incio o final   
Hola Mundo
Hola mundo
          hola mundo
     hola mundo     
20
hola rudo
 hola mundo
hola mundo

Para ver mas dar s. y luego tab y aparecerán los propiedades y metodos del objeto, seleccionar uno y poner ? antes

#s.
? s.count
Docstring:
S.count(sub[, start[, end]]) -> int

Return the number of non-overlapping occurrences of substring sub in
string S[start:end].  Optional arguments start and end are
interpreted as in slice notation.
Type:      builtin_function_or_method

Listas

Python tiene 4 tipos integrados de Contenedores: Listas, Tuplas, Diccionarios, Conjuntos

Lists, Tuple, Diccionaries, Sets

Una Lista es el equivalente a un arreglo

Las listas son “unidimensionales” y se delimitan por corchetes, parentesis cuadrados.

Los elementos de una lista se separaan por comas.

Las listas son variables, en el sentido de que su contenido puede cambiarse.

Un vector xRnx \in \mathbb{R}^n lo puede representar como una lista de nn floats!

¡Noten que escribí LATEX!

Los arreglos bidimensionales son en realidad listas de listas: vectores de vectores,

Los trimensionales seran listas de listas de listas y asi.

x = [4.2, 6.3, 3., 7.3]  # las listasn son unidimensionales, separadas por comas
print(x)            # la variable x a sido entera, luego string y ahora es una lista de flotantes!
print(type(x))      # tipo lista
print("Numero de elementos = ", len(x))       # de "tantos" elementos
print(x[1])         # elemento con índice 1: es el segundo
print(x[0])         # primer elemento de la lista
print(x[-1])        # ultimo elemento de la lista
[4.2, 6.3, 3.0, 7.3]
<class 'list'>
Numero de elementos =  4
6.3
4.2
7.3
x[2] = s            # reemplazando un elemento de la lista     
print(x)            # imprimiendo la lista actualizada
[4.2, 6.3, 'hola mundo', 7.3]

Ordenando Listas

x = [4.2, 6.3, 3., 7.3]
x.sort()
print(x)
[3.0, 4.2, 6.3, 7.3]

Pila Básica con listas

# simulando un PILA (Ultimas entradas, primeras Salidas) con una lista
pila = []    # pila incialmente vacia
print(pila)
[]
pila.append(5)       # añade un elemento al final de la pila
pila.append(4)
pila.append(3)
pila.append(2)
pila.append(1)
print(pila)
[5, 4, 3, 2, 1]
y = pila.pop()  # remueve el ultimo elemento de la pila
print(pila, y)
[5, 4, 3, 2] 1
pila.pop()      # hagamos varios pops a la pila hasta que quede vacia y demos uno mas. ala vacia a ver que pasa, 

# ¿como resolver el problema de tratar de sacar algo de una pila vacia sin que mi programa falle? 
2

Cola Básica con listas

La función incert() de las listas recibe dos parámetros:

  1. índice en donde incertar el elemento, el nuevo elemento quedará delante del indicado por este parámetro

  2. elemento a incertar

# Una Cola (FIFO), primeras entradas, primeras salidas
pila=[]
pila.insert(0,5)  # se incerta en nuevo elemento tal que quede con el índice antes del elemento 0 
pila.insert(0,4)
pila.insert(0,3)
pila.insert(0,2)
pila.insert(0,1)
print(pila)
print(pila, pila.pop()) # se extrae el primero que se incertó
[1, 2, 3, 4, 5]
[1, 2, 3, 4] 5

Selección de sublistas (Slicing)

Para extraer sublistas python tienen una notación inspirada en matlab:

x[a:b]

Esto es equivalente a [xa,xa+1,xa+2,xb1][x_a, x_{a+1}, x_{a+2} \ldots, x_{b-1}], es decir el elemento indexado por b no se regresa.

x = [4.2, 'bueno', 6.3,'casa', 'ml', 3., 7.3, 'hola']
print(x)
# usar dos parametros, por default se refiere a los extremos
print(x[0:len(x)])   # desde el elemento indexado por 0, hasta el antes del elemento indexado por len(x)
print(x[:])          # lista desde el inico hasta el ultimo, se puede omitir uno o los dos    
                     # terminaciones y se toma por default el extremo
[4.2, 'bueno', 6.3, 'casa', 'ml', 3.0, 7.3, 'hola']
[4.2, 'bueno', 6.3, 'casa', 'ml', 3.0, 7.3, 'hola']
[4.2, 'bueno', 6.3, 'casa', 'ml', 3.0, 7.3, 'hola']

Mas generalmente

sequencia[inicio:fin:paso]

inicio: indice del prmer caracter a regresar. Default es 0

fin: indice del terminacion de la rebanada; no se incluye el elemento indexado. Default es -1

paso: tamaño de incremento del índice. Default es 1

Una secuencia (lista), sus indices positivos (iniciando por la izquieda) y sus índices negativos (iniciando por la derecha)

x = [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(x[-len(x):])
print(x[::-1])
print(x[2::3])
x[5] = "hola"
print(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[2, 5, 8, 11, 14, 17]
[0, 1, 2, 3, 4, 'hola', 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Una lista de listas

X = [ [ 11, 12, 13, 14], 
      [ 21, 22, 23, 24], 
      [ 31, 32, 33, 34] ]

print(X)       # todo el objeto
print(X[0])    # el elemnto cero de la lista X, que es a su vez una lista
print(X[0][1]) # del primer elemento (lista), el segundo elemento 

# suponga que quremos extraer 
'''
X = [ [ 22, 23], 
      [ 32, 33] ]
'''
print(X[1:3][1:3])      # probemos.       
[[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]]
[11, 12, 13, 14]
12
[[31, 32, 33, 34]]
print([x[1:3] for x in X[1:3]]) # probemos
[[22, 23], [32, 33]]

¿Pero que que es esto? Es List Comprehension

Ciclos (Loops)

Para entender List Comprehension introduciremos el mecanismo de ciclos de Python

Es el mecanimo de iteración de Python

Es necesario iterar sobre los elementos de objetos que acepten iteradores: Contenedores (Listas, por ejemplo)

alumnos = ['Juan', 'Pedro','Elsa','Ana', 'Alberto','Judith','Miguel', 'Oscar','Laura', 'Jose', 'Roberto', 'Andres', 'Maria']

for alumno in alumnos:
    print ('{} es alumno de mi clase'.format(alumno))
# end for alumno

print ('Fin de lista')
Juan es alumno de mi clase
Pedro es alumno de mi clase
Elsa es alumno de mi clase
Ana es alumno de mi clase
Alberto es alumno de mi clase
Judith es alumno de mi clase
Miguel es alumno de mi clase
Oscar es alumno de mi clase
Laura es alumno de mi clase
Jose es alumno de mi clase
Roberto es alumno de mi clase
Andres es alumno de mi clase
Maria es alumno de mi clase
Fin de lista

Note la notación tipo xX:\forall x \in X:

El comando del ciclo termina con dos puntos (:)

El cuerpo de ciclo esta indentado, de hecho el editor lo hizo automáticamente.

No hay un end para delimitar el ciclo, se delimita por el fin de la identación.

Dado que la identación hace legibles los programas, en Python no de dejo opcional, es forzada (parte del diseño del lenguaje)

alumnos.sort()
print(alumnos)
['Alberto', 'Ana', 'Andres', 'Elsa', 'Jose', 'Juan', 'Judith', 'Laura', 'Maria', 'Miguel', 'Oscar', 'Pedro', 'Roberto']

Funcion enumerate

La función enumerate devuelve un objeto enumerado. -> indice (iniciando en cero), objeto (valor)

for idx, alumno in enumerate(alumnos):
    print(idx+1, alumno)
1 Alberto
2 Ana
3 Andres
4 Elsa
5 Jose
6 Juan
7 Judith
8 Laura
9 Maria
10 Miguel
11 Oscar
12 Pedro
13 Roberto

Funcion range

Regresa un objeto que produce una secuencia de enteros entre inico (inclusive) y fin (exclusive), separados por un paso

range([inicio,] fin)

range(inico, fin [, paso])

# imprime el objeto rango
x =range(2,10,3)
print(x)
range(2, 10, 3)
# imprime los valores en la secuencia del objeto rango
for y in x:
    print(y)
2
5
8

Imprimir un objeto rango no imprime la lista, esta solo se genera cuando se itera sobre dicho objeto

Esto permite ahorrar memoria

La forma de generar una lista a partrir de un objeto rango es usar la funcion list()

l = list(range(2,10,3))     # genera una lista
t = tuple(range(2,10,3))    # genera una 'tupla', veremos mas delante la diferencia, 
print('lista = ', l, '  tupla = ', t)        # note los parentesis en vez de braquets
lista =  [2, 5, 8]   tupla =  (2, 5, 8)

Comprensión de Listas (List Comprehension)

El procesamiento de Listas en mas eficiente si se realiza mediante List Comprehensions que mediante Loops:

Por ejemplo: generar una seciancia de los cuadrados de los numeros pares entre 0 y 20.

# solucion mediante Loops

quad=[]
for i in range(0,20,2):
    quad.append(i**2)

print(quad)

# otra versión aun mas larga
quad=[]
for i in range(0,20):
    if i%2==0:
        quad.append(i**2)

print(quad)
[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
# solución mediante List Comprehnsions
quad = [i**2 for i in range(0,20,2)]
print(quad)
[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
# incluyendo condiciones!
quad = [i**2 for i in range(0,20) if i%2==0]   
print(quad)
[0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
l = ['a', 'b', 'c']
n = ['1', '2']

# listas con todos los posibles pares
ln=[[x,y] for x in l for y in n]

# concatenación 
strln = [x+y for x in l for y in n]

print(ln)
print(ln[0])
print(ln[0][0])
print(ln[0][1])

print(strln)
[['a', '1'], ['a', '2'], ['b', '1'], ['b', '2'], ['c', '1'], ['c', '2']]
['a', '1']
a
1
['a1', 'a2', 'b1', 'b2', 'c1', 'c2']
LN = []
for x in ['a', 'b', 'c']:    # ahora in versión con Loops
    for y in ['1', '2']:
        LN.append([x,y])

print(LN)
[['a', '1'], ['a', '2'], ['b', '1'], ['b', '2'], ['c', '1'], ['c', '2']]

Tuplas

*Se comportan como listas constantes,

*Se delimitan por parentesis, ( )

*No pueden ser modificadas

*Pueden contener elementos de distintos tipos

*Se indexan (slicing) con corchetes igual que las listas

x = ( 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
print(x)
print(x[-len(x):])
print(x[0], x[-1])
x[5] = "hola"       # error, no se puede modificar una lista!   
print(x)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
0 19



---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-37-53a582b3a1cd> in <module>()
      3 print(x[-len(x):])
      4 print(x[0], x[-1])
----> 5 x[5] = "hola"       # error, no se puede modificar una lista!
      6 print(x)


TypeError: 'tuple' object does not support item assignment
# se crea una nueva tupla, destruyendo el contenido anterior
x = ( 0,  1,  2,  "hola",  4,  5,  6,  "mundo",  8,  9, 10, 11, 12)
print(x)
(0, 1, 2, 'hola', 4, 5, 6, 'mundo', 8, 9, 10, 11, 12)

Asignación Múltiple

Python permite en una misma línea asignar varias variables a la vez

a,b,c = 1, 2, 3
print(a,b,c)
a,b,c = b,c,a   
print(a,b,c)
1 2 3
2 3 1

Entonces para hacer intercambio de variables no es necesario usar variables temporales

a,b = 5,10
a,b = b,a  # swap!
print(a,b)
10 5

Explicación: Python construye una tupla temporal (obvia los parentesis) y hace la respectiva referenciación a los nuevos valores.

Variables en Python: ¿Almacenan Valores o Referencias?

En lenguajes como C, las variables almacenan valores, dichos valores pueden ser referencias a otras variables (apuntadores).

En Python, las variables son referencias.

(a,b,c) = (1,2,3)  # construyo una tupla con tres variables haciendo refencia a los valores 1,2,3
t       = (a,b,c)  # t es una tupla con tres elementos que hacen referencia a los valores de a,b,c
a +=10             # ¿puedo cambiar el valor de a?
print(a)     
11
print(t)         # ¿cuanto vale t?
(1, 2, 3)
print(t[0]+=10)  # ¿puedo modificar t?
  File "<ipython-input-43-bd5cc37b65db>", line 1
    print(t[0]+=10)  # ¿puedo modificar t?
               ^
SyntaxError: invalid syntax

Diccionarios

*Almacenan pares: llave : valor

*Se delimitan por llaves {brackets}

*Los pares se separan por comas

*Se accesan a traves de las llaves

d = {'pez': 'tiburon', 'mamifero':'vaca', 'numero': 3, 'irracional': 3.14}

print(d)
print(d['pez'])
print('numero' in d)
print('ave' in d)
print('irracional' in d)
print('vaca' in d)   # no es una llave
{'pez': 'tiburon', 'mamifero': 'vaca', 'numero': 3, 'irracional': 3.14}
tiburon
True
False
True
False
# pasando llaves a una lista mediante comprehensions
print([x for x in d])
['pez', 'mamifero', 'numero', 'irracional']

Conjuntos (Sets)

La notación es parecida a los listas, solo que no tienen un orden establecido

mascotas = {'perro', 'gato', 'pajaro', 'tortuga', 'pez', 'conejo','lagartija'}
mascotasList = [x for x in mascotas]

print(mascotas)
print(mascotasList)

{'perro', 'lagartija', 'pez', 'pajaro', 'gato', 'conejo', 'tortuga'}
['perro', 'lagartija', 'pez', 'pajaro', 'gato', 'conejo', 'tortuga']
print(mascotas.sort())  # los conjuntos (*set*) no son ordenables!
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-47-41bfa90c8885> in <module>()
----> 1 print(mascotas.sort())  # los conjuntos (*set*) no son ordenables!


AttributeError: 'set' object has no attribute 'sort'
mascotasList.sort()
print(mascotasList)
['conejo', 'gato', 'lagartija', 'pajaro', 'perro', 'pez', 'tortuga']
# conjunto vacio
d = {}
print(d)
{}

Fin de Tema