Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
EL LENGUAJE DE PROGRAMACIÓN
PYTHON
Juan Ignacio Rodríguez de León
jileon en twitter
euribates @ gmail.com
Nombres de variables
and
and elif
elif if
if print
print
as
as else
else import
import raise
raise
assert
assert except
except in
in return
return
break
break exec
exec is
is try
try
class
class finally
finally lambda
lambda while
while
continue
continue for
for not
not with
with
def
def from
from or
or yield
yield
del
del global
global pass
pass
Tipos de datos
– Valores – Listas
Lógicos – Tuplas
– Números – Diccionarios
– Textos – Conjuntos
Valores lógicos o booleanos
xor y not
● Normalmente,
resultado de alguna
comparación: ==, <,
<=, >, >=
George Bool
Números
– Enteros
– Reales
– Decimal
– Complejos
Operaciones con números
Sumas y restas: + y -
Multiplicación y división: * y /
División entera: //
Módulo: %
Exponenciación: **
AND a nivel de bits: &
OR a nivel de bits: |
XOR a nivel de bits: ^
Enteros
Se crea una variable entera asignandole
un valor entero
Asignación múltiple
No hay tamaño máximo para el numero,
excepto por la memoria disponible
Calculemos en python 2 elevado a 2048
>>>
>>> aa == 425
425
>>>
>>> bb == cc == dd == ee == 99
99
>>>
>>> 2**2048
2**2048
Reales o en coma flotante
– a = 23.0
– b = 3.141592653589793
– c = .23
– d = 1e-3
Ejercicio
¿Cuál creen que será el resultado?
aa ==
0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
bb == 1.0
1.0
aa ==
== bb
TRUE FALS
E
FALS
E
Las culpas, a IEEE 754
IEEE 754 estándar de la IEEE para aritmética
en coma flotante
Afecta a prácticamente todos los lenguajes:
Java, C, C++...
Algunos números no tienen representación
exacta
Los errores pueden acumularse
Solución: redondeo y fijar precisión
… o usar el tipo decimal
Tipo decimal
>>>
>>> aa == [1,2,3,4]
[1,2,3,4]
>>>
>>> a[1:3]
a[1:3] == [2.0,
[2.0, 2.1,
2.1, 2.3,
2.3, 2.5,
2.5, 2.7,
2.7, 2.9,
2.9, 3.0]
3.0]
>>>
>>> print(a)
print(a)
[1,
[1, 2.0,
2.0, 2.1,
2.1, 2.3,
2.3, 2.5,
2.5, 2.7,
2.7, 2.9,
2.9, 3.0,
3.0, 4]
4]
>>>
>>> a[:]
a[:] == []
[] ## Borramos
Borramos toda
toda la
la lista
lista
>>>
>>> print(a)
print(a)
[]
[]
La función len
La función len(), que en el caso de las
cadenas de textos nos retornaba su
longitud, aplicada a una lista nos
devuelve el número de elementos de la
lista.
>>>
>>> ll == [1,True,3.0,'hola']
[1,True,3.0,'hola']
>>>
>>> print(len(l))
print(len(l))
44
>>>
>>> ss == '¡Es
'¡Es una
una trampa!'
trampa!'
>>>
>>> print(len(s))
print(len(s))
16
16
¿Qué podemos guardar en listas?
>>>
>>> aa == [[1,2,3],
[[1,2,3], [4,5,6],
[4,5,6], [7,8,9]]
[7,8,9]]
>>>
>>> print(a[0][0])
print(a[0][0])
11
>>>
>>> print(a[1][1])
print(a[1][1])
55
>>>
>>> print(len(a))
print(len(a))
33
Pregunta
No debemos olvidar que las listas son
mutables, porque puede causar muchos
problemas en el programador novato. Por
ejemplo, dado el siguiente fragmento de
código, ¿Qué saldrá impreso por pantalla?
¿Por qué?
qq == ['a',
['a', 'b']
'b']
pp == [1,
[1, q,
q, 4]
4]
q.append('extra')
q.append('extra')
print(p)
print(p)
Comparar listas
– Cadenas de texto
– Listas
– … más cosas que veremos
Ejemplos
>>>
>>> for
for letra
letra in
in 'Texto':
'Texto': print(letra)
print(letra)
...
...
TT
ee
xx
tt
oo
>>>
>>> for
for ww in
in ['Se',
['Se', 'acerca',
'acerca', 'el',
'el', 'invierno']:
'invierno']:
...
... print(w,
print(w, len(w))
len(w))
...
...
Se
Se 22
acerca
acerca 66
el
el 22
invierno
invierno 88
Modificar la lista en marcha
>>>
>>> words
words == ['Se',
['Se', 'acerca',
'acerca', 'el',
'el', 'invierno']
'invierno']
>>>
>>> for
for ww in
in words[:]:
words[:]:
...
... if
if len(w)
len(w) << 4:
4:
...
... words.remove(w)
words.remove(w)
Pero yo quiero mis índices...
Si tenemos que iterar sobre un rango de
números, la función predefinida range()
devuelve una secuencia iterable
Acepta entre uno y tres parámetros
– range(10) → [0,1,2,3,4,5,6,7,8,9]
– range(4,8) → [4,5,6,7]
– range(1,7,2) → [1,3,5]
El límite superior nunca se alcanza
Me gusta range...
Si tenemos experiencia en otros lenguajes,
podemos sentir la tentación de usar range()
cada vez que hagamos un for; es decir, hacer:
word
word == 'ABCD'
'ABCD'
for
for ii in
in range(len(word)):
range(len(word)):
letra
letra == word[i]
word[i]
print(letra)
print(letra)
En vez de
for
for letra
letra in
in 'ABCD':
'ABCD':
print(letra)
print(letra)
Me gusta range (2)
NO
¡Que no!
>>>
>>> for
for i,
i, letra
letra in
in enumerate('ABCD'):
enumerate('ABCD'):
...
... print(i,
print(i, letra)
letra)
00 AA
11 BB
22 CC
33 DD
>>>
>>>
El bucle while
acc
acc == num
num == 11
while
while acc
acc ** (num+1)
(num+1) << 1000000:
1000000:
num
num == num
num ++ 11
acc
acc == num
num ** acc
acc
print('El
print('El mayor
mayor factorial
factorial menor
menor que
que 1E6
1E6 es:
es: ',
',
num,
num, '!
'! == ',
', acc,
acc, sep='')
sep='')
While
La sentencia while encaja perfectamente
cuando no sabemos a priori cuando
debemos parar.
Si sabemos de antemano la cantidad de
vueltas que tenemos que dar, parece más
natural usar for
El error más común con un bucle de este
tipo es olvidarnos de actualizar, dentro
del código del bucle, la variable que es
testeada en la condición del while
break, continue y else en bucles
● La sentencia break fuerza la salida del bucle
for o while en la que se encuentre
● Si hay varios bucles anidados, solo saldrá del
más interno
● Hay veces que no tiene sentido continuar con el
bucle
● Por ejemplo, buscar dentro de una lista de
números uno que sea múltiplo de 7,
(simplemente nos interesa encontrar uno, el
primero que encuentre), no tiene sentido seguir
recorriendo el bucle hasta el final
Ejemplo de break
>>>
>>> numeros
numeros == [15,53,98,36,48,52,27,4,29,94,13]
[15,53,98,36,48,52,27,4,29,94,13]
>>>
>>> for
for nn in
in numeros:
numeros:
...
... if
if nn %% 77 ==
== 0:
0:
...
... print(n,
print(n, 'es
'es múltiplo
múltiplo de
de 7')
7')
...
... break
break
...
...
98
98 es
es múltiplo
múltiplo de de 77
>>>
>>>
Else en bucles
>>>
>>> numeros
numeros == [87,39,85,72,41,95,93,65,26,11,32,17]
[87,39,85,72,41,95,93,65,26,11,32,17]
>>>
>>> for
for nn in
in numeros:
numeros:
...
... if
if nn %% 77 ==
== 0:
0:
...
... print(n,
print(n, 'es'es múltiplo
múltiplo de
de 7')
7')
...
... break
break
...
... else:
else:
...
... print
print ('No
('No hay
hay múltiplos
múltiplos de
de 77 en
en la
la lista')
lista')
...
...
No
No hay
hay múltiplos
múltiplos de de 77 en
en la
la lista
lista
Ejercicio
acc
acc == num
num == 11
while
while acc
acc ** (num+1)
(num+1) << 1000000:
1000000:
num
num == num
num ++ 11
acc
acc == num
num ** acc
acc
else:
else:
num
num == num
num ++ 11
acc
acc == num
num ** acc
acc
print('El
print('El número
número buscado
buscado es:')
es:')
print(num,
print(num, '!'! == ',
', acc,
acc, sep='')
sep='')
Solución con break
#############
#############
## con
con break
break ##
#############
#############
acc
acc == num
num == 11
while
while True:
True:
num
num == num
num ++ 11
acc
acc == num
num ** acc
acc
if
if acc
acc >> 1000000:
1000000:
print('El
print('El número
número buscado
buscado es:')
es:')
print(num,
print(num, '! '! == ',
', acc,
acc, sep='')
sep='')
break
break
Tuplas
Hemos visto que listas y cadenas de
texto tenian muchas cosas en comun,
como el poder ser accedidas mediante
índices y por rodajas
Hay más tipos de datos que comparten
estas propiedades, todos agrupados bajo
el nombre genérico de tipos de
secuencias de datos, como el que nos
ocupa ahora, las tuplas
Como crear tuplas
Como lista de valores separados con comas,
normalmente entre paréntesis. Las tuplas de un
elemento tienen que tener una coma al final.
>>>
>>> tt == 12.5,
12.5, 9560
9560 ++ 23,
23, 'hola'
'hola'
>>>
>>> t[0]
t[0]
12.5
12.5
>>>
>>> t[1]
t[1]
>>>
>>> 9583
9583
>>>
>>> tt
(12.5,
(12.5, 9583,
9583, 'hola')
'hola')
>>>
>>> tt ==
== (12.5,
(12.5, 9560
9560 ++ 23,
23, 'hola')
'hola')
True
True
>>>
>>> t2
t2 == ('hola',)
('hola',)
Diferencia con las listas
>>>
>>> a,
a, b,
b, cc == 1,
1, 2,
2, 33
>>>
>>> print(a,
print(a, b, b, c)
c)
11 22 33
>>>
>>> a,
a, bb == b,
b, aa
>>>
>>> print(a,
print(a, b) b)
22 11
Más operaciones de tuplas
dd == {{
'enero':
'enero': 1,
1, 'febrero':
'febrero': 2,
2, 'marzo':
'marzo': 3,
3,
'abril':
'abril': 4,
4, 'mayo':
'mayo': 5,
5, 'junio':
'junio': 6,
6,
'julio':
'julio': 7,
7, 'agosto':
'agosto': 8,
8, 'septiembre':
'septiembre': 9,
9,
'octubre':
'octubre': 10,
10, 'noviembre':
'noviembre': 11,
11, 'diciembre':
'diciembre': 12,
12,
}}
print('el
print('el mes
mes de
de {}
{} es
es el
el número
número {}'.format(
{}'.format(
'octubre',
'octubre', d['octubre']
d['octubre']
))
))
Métodos de los diccionarios
A nadie debería sorprender que len() también
funciona con diccionarios (y devuelve, por
supuesto, el número de valores almacenados en
el diccionario)
Las principales operaciones que podemos hacer
con un diccionario son almacenar un valor con
una determinada clave, o recuperar un valor a
partir de la clave
>>>
>>> dd == {}
{}
>>>
>>> d['hola']
d['hola'] == 'Mundo'
'Mundo'
>>>
>>> print(d['hola'])
print(d['hola'])
Mundo
Mundo
Más operaciones con diccionarios
clear()
– Vacia el diccionario
get(key, [default_value]) → item
– Si key está en el diccionario, entonces
devuelve el valor correspondiente, si no
está, devuelve default_value, que por
defecto es None
Métodos de los dicionarios (2)
Items() → lista de tuplas
– Devuelve una lista de 2-tuplas, donde cada tupla esta
constituida por una pareja clave, valor de cada
entrada del diccionario.
Keys() → lista
– Devuelve una lista de todas las claves usadas en el
diccionario.
pop(key, [default_value]) → item
– Devuelve el valor almacenado con la clave key, y
borra la entrada del diccionario. Si key no está en el
diccionario, devuelve el valor default_value si se ha
especificado, si no, eleva la excepcion KeyError.
Métodos de los dicionarios (3)
>>>
>>> ss == set(['a',
set(['a', 'e',
'e', 'i',
'i', 'o',
'o', 'u',
'u', 'a'])
'a'])
>>>
>>> print(s)
print(s)
>>>
>>> set(['a',
set(['a', 'i',
'i', 'e',
'e', 'u',
'u', 'o'])
'o'])
>>>
>>> len(s)
len(s)
55
>>>
>>> 'a'
'a' in
in ss
True
True
>>>
>>> 'f'
'f' in
in ss
False
False
Más operaciones con conjuntos
Cualquier operación del Algebra de Conjuntos:
Unión, Intersección, Diferencia, Complemento
>>>
>>> aa == set('PETER')
set('PETER') ## set(['P','R','E','T'])
set(['P','R','E','T'])
>>>
>>> bb == set('PARKER')
set('PARKER') ## set(['A','P','K','R','E'])
set(['A','P','K','R','E'])
>>>
>>> aa -- bb ## Letras
Letras en
en PETER,
PETER, pero
pero no
no en
en PARKER
PARKER
set(['T'])
set(['T'])
>>>
>>> bb -- aa ## Letras
Letras en
en PARKER,
PARKER, pero
pero no
no en
en PETER
PETER
set(['A',
set(['A', 'K'])
'K'])
>>>
>>> aa || bb ## Letras
Letras en
en PETER
PETER oo en
en PARKER
PARKER (Unión)
(Unión)
set(['A',
set(['A', 'E','E', 'K',
'K', 'P',
'P', 'R',
'R', 'T'])
'T'])
>>>
>>> aa && bb ## Letras
Letras en
en PETER
PETER yy en
en PARKER
PARKER (Intersección)
(Intersección)
set(['P',
set(['P', 'R','R', 'E'])
'E'])
>>>
>>> aa ^^ bb ## Letras
Letras en
en PETER
PETER oo PARKER,
PARKER, pero
pero no
no en
en los
los 22
set(['A',
set(['A', 'T','T', 'K'])
'K'])
Producto cartesiano
Para el producto tendremos que recurrir al
módulo de la librería estándar itertools.
No se preocupe si no se entiende por ahora
>>>
>>> import
import itertools
itertools
>>>
>>> aa == set('ABC')
set('ABC')
>>>
>>> bb == set('123')
set('123')
>>>
>>> pp == set(itertools.product(a,
set(itertools.product(a, b))
b))
>>>
>>> print(p)
print(p)
set([('C',
set([('C', '1'),
'1'), ('C',
('C', '2'),
'2'), ('C',
('C', '3'),
'3'),
('A',
('A', '2'),
'2'), ('A',
('A', '3'),
'3'), ('B',
('B', '3'),
'3'),
('A',
('A', '1'),
'1'), ('B',
('B', '2'),
'2'), ('B',
('B', '1')])
'1')])
Otros métodos interesantes
issubset(set) → boolean
– Indica si el conjunto es un subconjunto de otro
mayor, que se pasa como parametro
issuperset(set) → boolean
– Indica si el el conjunto incluye al que se le pasa
como parámetro.
isdisjoint(set) → boolean
– Indica si el subconjunto no tienen ningún
elemento en común con el que se le pasa como
parámetro.
Funciones
import
import math
math
def
def perimetro(r):
perimetro(r):
"""Devuelve
"""Devuelve elel perímetro
perímetro de
de
una
una circunferencia
circunferencia de de radio
radio r.
r.
"""
"""
return
return 22 ** math.pi
math.pi ** rr
radio
radio == 66
print('El
print('El perímetro
perímetro de
de una
una circunferencia
circunferencia de
de
radio',
radio', radio,
radio, 'es:',
'es:', perimetro(radio))
perimetro(radio))
¿Paso por referencia o por valor?
(Solo para academicos)
resaltar('Informe
resaltar('Informe sobre
sobre probabilidad
probabilidad A')
A')
resaltar('Informe
resaltar('Informe sobre
sobre probabilidad
probabilidad A',
A', '=')
'=')
----------------------------
----------------------------
Informe
Informe sobre
sobre probabilidad
probabilidad AA
----------------------------
----------------------------
============================
============================
Informe
Informe sobre
sobre probabilidad
probabilidad AA
============================
============================
Valores por defecto
Los valores por defecto se evaluan en el
momento y en el ámbito en que se realiza la
definición de la función. Sabiendo eso, ¿Que
imprimirá el siguiente código?
ii == 55
def
def f(arg=i):
f(arg=i):
print
print arg
arg
ii == 66
f()
f()
Ojo con valores mutables
>>>
>>> def
def f(a,
f(a, l=[]):
l=[]):
...
... l.append(a)
l.append(a)
...
... return
return ll
...
...
>>>
>>> print(f(1))
print(f(1))
[1]
[1]
>>>
>>> print(f(2))
print(f(2))
[1,
[1, 2]
2]
>>>
>>> print(f(3))
print(f(3))
[1,
[1, 2,
2, 3]
3]
>>>
>>>
¿Y si quiero que se cree cada vez?
(Que se ejecute)
def
def as_bin(n):
as_bin(n):
ss == bin(n)
bin(n)
ss == s[2:]
s[2:]
ss == '0'
'0' ** 11
11 ++ ss
return
return s[-11:]
s[-11:]
Llega más información de la ESA
def
def as_bin(n,
as_bin(n, width=11):
width=11):
ss == bin(n)
bin(n)
ss == s[2:]
s[2:]
ss == '0'
'0' ** width
width ++ ss
return
return s[-width:]
s[-width:]
Llega más información del IAC
def
def as_bin(n,
as_bin(n, width=11):
width=11):
ss == bin(n)
bin(n)
ss == s[2:]
s[2:]
ss == '0'
'0' ** width
width ++ ss
return
return s[-width:]
s[-width:]
data
data == [260,
[260, 136,
136, 508,
508, 886,
886, 2047,
2047, 1533,
1533, 1285,
1285, 216]
216]
for
for dd in
in data:
data:
print(as_bin(d,
print(as_bin(d, width=11))
width=11))
Resultado
00100000100
00100000100
00010001000
00010001000
00111111100
00111111100
01101110110
01101110110
11111111111
11111111111
10111111101
10111111101
10100000101
10100000101
00011011000
00011011000
Necesitamos aumentar el contraste
def
def as_blocks(s):
as_blocks(s):
output
output == ''
''
for
for cc in
in s:
s:
if
if cc ==
== '1':
'1':
output
output +=
+= u'\u2588\u2588'
u'\u2588\u2588'
elif
elif cc ==
== '0':
'0':
output
output +=
+= '' ''
else:
else:
raise
raise ValueError('No
ValueError('No es
es 1/0')
1/0')
return
return output
output
Analizamos las señales
print('Señal
print('Señal 1')
1')
data
data == [260,
[260, 136,
136, 508,
508, 886,
886, 2047,
2047, 1533,
1533, 1285,
1285, 216]
216]
for
for dd in
in data:
data:
print(as_blocks(as_bin(d,
print(as_blocks(as_bin(d, width=11)))
width=11)))
print('Señal
print('Señal 2')
2')
data
data == [240,
[240, 2046,
2046, 4095,
4095, 3687,
3687, 4095,
4095, 408,
408, 876,
876, 3075]
3075]
for
for dd in
in data:
data:
print(as_blocks(as_bin(d,
print(as_blocks(as_bin(d, width=12)))
width=12)))
print('Señal
print('Señal 3')
3')
data
data == [24,
[24, 60,
60, 126,
126, 219,
219, 255,
255, 36,
36, 90,
90, 165]
165]
for
for dd in
in data:
data:
print(as_blocks(as_bin(d,
print(as_blocks(as_bin(d, width=8)))
width=8)))
Confirmado: La señal es alienígena
Gracias por su colaboración
def
def area_triangulo(base=0,
area_triangulo(base=0, altura=0,
altura=0, a=0,
a=0, b=0,
b=0,
c=0):
c=0):
if
if base
base and
and altura
altura
return
return (base
(base ** altura)
altura) // 2.0
2.0
elif
elif aa and
and bb and
and c:
c:
ss == (a
(a ++ bb ++ c)
c) // 22
return
return math.sqrt(s*(s-a)*(s-b)*(s-c))
math.sqrt(s*(s-a)*(s-b)*(s-c))
else:
else:
raise
raise ValueError('Hay
ValueError('Hay que que especificar
especificar base
base
yy altura,
altura, oo los
los lados
lados a,b,c')
a,b,c')
print(area_triangulo(base=3,
print(area_triangulo(base=3, altura=4))
altura=4))
print(area_triangulo(a=3,
print(area_triangulo(a=3, b=4,
b=4, c=5))
c=5))
print(area_triangulo())
print(area_triangulo())
Parámetros arbitrarios
por posición o por nombre
>>>
>>> def
def dump(**kwargs):
dump(**kwargs):
...
... for
for name
name in
in kwargs:
kwargs:
...
... print(name,
print(name, kwargs[name])
kwargs[name])
...
...
>>>
>>> dump(a=1,
dump(a=1, b=2,
b=2, c=3)
c=3)
aa 11
bb 22
cc 33
>>>
>>> dump(hola='mundo')
dump(hola='mundo')
hola
hola mundo
mundo
Listas, tuplas o diccionarios como
parámetros
A veces, queremos hacer lo contrario, una función
que acepta n parámetros, y nosotros tenemos
esos parámetros en una lista o tupla.
En vez de desempaquetarlos a mano, podemos
usar la sintaxis * para pasar la tupla directamente
>>>
>>> range(3,
range(3, 6)
6) ## Llamada
Llamada normal
normal
[3,
[3, 4,
4, 5]
5]
>>>
>>> args
args == [3,
[3, 6]
6]
>>>
>>> range(*args)
range(*args) ## Llamada
Llamada con
con parámetros
parámetros empaquetados
empaquetados
[3,
[3, 4,
4, 5]
5]
>>>
>>>
Tambien con diccionarios
(usando **)
def
def area_triangulo(base,
area_triangulo(base, altura):
altura):
return
return (base
(base ** altura)
altura) // 2.0
2.0
datos
datos == {'base':3,
{'base':3, 'altura':
'altura': 4}
4}
print(area_triangulo(**datos))
print(area_triangulo(**datos))
Funciones Lambda
Parte del soporte de programación funcional
Capacidad de crear pequeñas funciones anónimas,
mediante la palabra reservada lambda
Por ejemplo, esta es la definición de una función que
suma los dos parámetros que se le pasan:
lambda(x,y):
lambda(x,y): x+y
x+y
def
def fib2(n):
fib2(n): ## return
return Fibonacci
Fibonacci series
series up
up to
to nn
result
result == [][]
a,
a, bb == 0,
0, 11
while
while bb << n:
n:
result.append(b)
result.append(b)
a,
a, bb == b,
b, a+b
a+b
return
return result
result
Importación parcial