In [1]:
"""
IPython Notebook v4.0 para python 2.7
Librerías adicionales: Ninguna.
Contenido bajo licencia CC-BY 4.0. Código bajo licencia MIT. (c) Sebastian Flores.
"""
# Configuracion para recargar módulos y librerías
%reload_ext autoreload
%autoreload 2
from IPython.core.display import HTML
HTML(open("style/iwi131.css", "r").read())
Out[1]:
Diccionarios son una de las formas más comunes y versátiles de almacenar información.
Junto con listas, tuplas y conjuntos, completan las estructuras de almacenamiento básicas.
Son mi estructura de datos preferida.
El diccionario es "como una lista" excepto que:
In [3]:
d = {"alpha":1, "beta":[1,1,3,5], (0,1):"beta"}
print d # No hay orden!!
In [4]:
telefonos = {'Pepito': 5552437, 'Jaimito': 5551428,
'Yayita': 5550012, 'NN':6626288}
In [5]:
# Paréntesis cuadrados para acceder a valores, como en listas o tuplas.
print telefonos['Jaimito']
print telefonos['Yayita']
# Funciones especiales
print "Llaves: ", telefonos.keys() # Lista de todas las llaves
print "Valores: ", telefonos.values() # Lista de todos los valores
In [7]:
#print telefonos['N'] # Llave no existe
print telefonos[5552437] # No se accede a llave por valor.
In [12]:
d = {} # Diccionario vacío: {} o dict()
d['a'] = 8
d['b'] = 5
d['c'] = 12
d['lista'] = []
print(d)
d['c'] *= -1
d['lista'].append(5)
d['d'] = 5
d['e'] = -10
d['lista'].append(8)
d['lista'] = "VACIA"
del d['e']
d['b'] = (d['b'], 10)
print(d)
Podemos aplicar los siguientes métodos sobre un diccionario:
dict.keys()
: Regresa la lista de las llaves. dict.values()
: Regresa la lista de los valores.dict.items()
: Regresa una lista con todos los pares (llave, valor).key in dict
: Regresa un booleano que indica si la llave key
ya está en las llaves del diccionario.
In [15]:
patas = {'humano': 2, 'pulpo': 8, 'perro': 4, 'gato': 4, 'ciempies': 100}
print patas
print "patas.keys():", patas.keys()
print "patas.values():", patas.values()
print "patas.items():", patas.items()
print "list(patas):", list(patas)
print "'perro' in patas:", 'perro' in patas
print "8 in patas:", 8 in patas
print "8 in patas.values():", 8 in patas.values()
print "len(patas):", len(patas)
print "promedio patas: ", sum(patas.values()) /float(len(patas))
Escriba una función contrar_letras(palabra) que reciba un string y retorne un diccionario que indique cuantas veces aparece cada letra en el string. Por ejemplo:
In [17]:
def contar_letras(palabra):
# Inicializar diccionario vacío
letras={}
# Recorrer las letras de la palabra
for c in palabra:
if not c in letras:
letras[c]=1
else:
letras[c]+=1
# Para cada letra, ver si no está inicializar (=0) y/o aumentar (+=1)
# Regresar el resultado
return letras
# Verificacion
print(contar_letras('entretener')) # {'n': 2, 'e': 4,'r': 2, 't': 2}
print(contar_letras('lapiz')) # {'a': 1, 'i': 1, 'l': 1, 'p': 1, 'z': 1}
Escriba una función contrar_letras(palabra) que reciba un string y retorne un diccionario que indique cuantas veces aparece cada letra en el string. Por ejemplo:
In [19]:
# Solución
def contar_letras(palabra):
# Inicializar diccionario vacío
cuentas = {}
# Recorrer las letras de la palabra
for letra in palabra:
# Para cada letra, ver si no está inicializar (=0) y/o aumentar (+=1)
if letra not in cuentas:
cuentas[letra] = 0
cuentas[letra] = cuentas[letra] + 1
# Regresar el resultado
return cuentas
# Verificacion
print(contar_letras('entretener')) # {'n': 2, 'e': 4,'r': 2, 't': 2}
print(contar_letras('lapiz')) # {'a': 1, 'i': 1, 'l': 1, 'p': 1, 'z': 1}
Notar que los diccionarios no tienen orden. La primera letra ingresada no es la primera letra que se muestra.
In [20]:
# Manera directa, sobre las llaves
capitales = {'Chile': 'Santiago', 'Peru': 'Lima', 'Ecuador': 'Quito',}
for pais in capitales:
print('La capital de '+pais+' es '+capitales[pais])
In [23]:
# Manera indirecta, sólo sobre los valores
for capital in capitales.values():
print capital,' es una linda ciudad'
In [22]:
# Simultáneamente sobre llaves y valores
for pais, capital in capitales.items():
print(capital+' es la capital de '+pais)
Dadas 4 listas de nombres, apellidos, rol y carrera, escriba una función que entregue un diccionario que a cada rol asigne una tupla con nombre completo y carrera:
roles = ["2004001-7", "2004007-3", "007-K"]
nombres = ["Sebastian", "Maria Jose", "James"]
apellidos = ["Flores", "Vargas", "Bond"]
carreras = ["ICM", "ICI", "AS"]
print diccionarizame(roles, nombres, apellidos, carrera)
{'2004007-3': ('Maria Jose Vargas','ICI'),
'007-K': ('James Bond', 'AS'),
'2004001-7': ('Sebastian Flores', 'ICM')}
In [24]:
def diccionarizame(roles, nombres, apellidos, carreras):
# FIX ME
dic = {}
for i in range(len(roles)):
rol = roles[i]
nombre = nombres[i]
apellido = apellidos[i]
carrera = carreras[i]
nombre_completo = nombre +' '+ apellido
dic[rol] = (nombre_completo, carrera)
return dic
roles = ["2004001-7", "2004007-3", "007-K"]
nombres = ["Sebastian", "Maria Jose", "James"]
apellidos = ["Flores", "Vargas", "Bond"]
carreras = ["ICM", "ICI", "AS"]
print diccionarizame(roles, nombres, apellidos, carreras)
In [ ]:
# Solucion
def diccionarizame(roles, nombres, apellidos, carreras):
d = {}
for i in range(len(roles)):
rol = roles[i]
nombre = nombres[i] + " " + apellidos[i]
carrera = carreras[i]
d[rol] = (nombre, carrera)
return d
roles = ["2004001-7", "2004007-3", "007-K"]
nombres = ["Sebastian", "Maria Jose", "James"]
apellidos = ["Flores", "Vargas", "Bond"]
carreras = ["ICM", "ICI", "AS"]
print diccionarizame(roles, nombres, apellidos, carreras)
Escriba una función invertir(d) que entregue un diccionario cuyas llaves sean los valores de d y cuyos valores sean las llaves respectivas:
print invertir({1: 2, 3: 4, 5: 6})
{2: 1, 4: 3, 6: 5}
apodos = {
'Suazo': 'Chupete',
'Sanchez': 'Maravilla',
'Medel': 'Pitbull',
'Valdivia': 'Mago',
}
print invertir(apodos)
{'Maravilla': 'Sanchez', 'Mago': 'Valdivia',
'Chupete': 'Suazo', 'Pitbull': 'Medel'}
In [26]:
def invertir(d):
# FIX ME
p = {}
for llave, valor in d.items():
p[valor] = llave
return p
print invertir({1: 2, 3: 4, 5: 6})
apodos = {
'Suazo': 'Chupete',
'Sanchez': 'Maravilla',
'Medel': 'Pitbull',
'Valdivia': 'Mago',
}
print invertir(apodos)
In [ ]:
# Solución
def invertir(d):
d_inv = {}
for k,v in d.items():
d_inv[v] = k
return d_inv
print invertir({1: 2, 3: 4, 5: 6})
apodos = {
'Suazo': 'Chupete',
'Sanchez': 'Maravilla',
'Medel': 'Pitbull',
'Valdivia': 'Mago',
}
print invertir(apodos)
In [ ]:
def maximo(d):
# FIX ME
return
numeros = {"uno":1, "dos": 2, "tres":3, "mil":1000, "infinito":float("inf")}
k = maximo(numeros)
print k
print numeros[k]
In [27]:
def maximo(d):
key_max = ""
val_max = -float("inf")
for key, val in d.items():
if val>val_max:
key_max = key
val_max = val
return key_max
numeros = {"uno":1, "dos": 2, "tres":3, "mil":1000, "infinito":float("inf")}
k = maximo(numeros)
print k
print numeros[k]
In [29]:
usuarios = {
522514: ('Jean Dupont', 'Marseille', (1989, 11, 21)),
587125: ('Perico Los Palotes', 'Valparaiso', (1990, 4, 12)),
587126: ('Mauricio Isla', 'Marseille', (1988, 6, 12)),
189471: ('Jan Kowalski', 'Krakov', (1994, 4, 22)),
914210: ('Antonio Nobel', 'Valparaiso', (1988, 7, 1)),
# ...
}
In [30]:
def misma_ciudad(u1,u2):
# FIX ME
nombre1,ciudad1,fecha1=usuarios[u1]
nombre2,ciudad2,fecha2=usuarios[u2]
return ciudad1==ciudad2
print misma_ciudad(914210, 587125)
print misma_ciudad(522514, 189471)
In [31]:
def misma_ciudad(u1,u2):
return usuarios[u1][1]==usuarios[u2][1]
print misma_ciudad(914210, 587125)
print misma_ciudad(522514, 189471)
In [ ]:
def diferencia_edad(u1,u2):
# FIX ME
return
print diferencia_edad(914210, 587125)
print diferencia_edad(522514, 189471)
In [ ]:
def diferencia_edad(u1,u2):
name1,city1,(year1,month1,day1) = usuarios[u1]
name2,city2,(year2,month2,day2) = usuarios[u2]
return abs(year1-year2)
print diferencia_edad(914210, 587125)
print diferencia_edad(522514, 189471)
Para guardar la información sobre cuáles de sus usuarios son amigos entre sí, BookFace utiliza el conjunto amistades, que contiene tuplas con los códigos de dos usuarios. Si la tupla (a, b) está dentro del conjunto, significa que los usuarios con códigos a y b son amigos. En todas las tuplas se cumple que $a<b$ (la tupla aparece una única vez).
In [ ]:
amistades = [ (522514, 914210),
(587125, 914210),
(587126, 914210),
(189471, 587125), # ...
]
In [ ]:
def obtener_amigos(u):
# FIX ME
return
print obtener_amigos(914210)
In [ ]:
def obtener_amigos(u):
amigos = []
for v,w in amistades:
if v==u:
amigos.append(w)
if w==u:
amigos.append(v)
return amigos
print obtener_amigos(914210)
b) Escriba la función recomendar_amigos(u)
, que retorne una lista con los código de los usuarios que cumplen todas estas condiciones a la vez:
In [ ]:
def recomendar_amigos(u):
# FIX ME
return
recomendar_amigos(522514)
In [ ]:
def recomendar_amigos(u):
amigos_actuales = obtener_amigos(u)
nuevos_amigos = []
for amigo in amigos_actuales:
for candidato in obtener_amigos(amigo):
bool_ciudad = misma_ciudad(u, candidato)
bool_edad = ( diferencia_edad(u,candidato) < 10)
bool_no_amigos = ( candidato not in amigos_actuales)
bool_no_mismo = ( candidato != u )
if bool_ciudad and bool_edad and bool_no_amigos and bool_no_mismo:
nuevos_amigos.append(candidato)
return nuevos_amigos
codigos = recomendar_amigos(522514)
for c in codigos:
print usuarios[c]