20/10 Tipos de datos compuestos. Estructuras de control repetitivas. Índices y slices Diccionarios como acumuladores/contadores

Listas


In [1]:
lista_de_numeros = [1, 6, 3, 9, 5, 2]
print lista_de_numeros
print type(lista_de_numeros)


[1, 6, 3, 9, 5, 2]
<type 'list'>

Es fácil saber si un número está en la lista o no:


In [2]:
print 'El %s esta en %s?: %s' % (5, lista_de_numeros, 5 in lista_de_numeros)
print 'El %s esta en %s?: %s' % (7, lista_de_numeros, 7 in lista_de_numeros)


El 5 esta en [1, 6, 3, 9, 5, 2]?: True
El 7 esta en [1, 6, 3, 9, 5, 2]?: False

El operador in también funciona para strings (es case sensitive):


In [3]:
print 'mundo in "Hola mundo": ', 'mundo' in "Hola mundo"
print 'MUNDO in "Hola mundo": ', 'MUNDO' in "Hola mundo"


mundo in "Hola mundo":  True
MUNDO in "Hola mundo":  False

In [4]:



[1, 2, 3, 5, 6, 9]
[9, 6, 5, 3, 2, 1]

O modificar un elemento de la lista:


In [5]:
lista_de_numeros[3] = 152
print lista_de_numeros


[1, 6, 3, 152, 5, 2]

En ningún momento dijimos que la lista era de enteros, por lo que tranquilamente podemos guardar elementos de distintos tipos de datos


In [6]:
lista_de_cosas = [2, 5.5, 'letras', [1, 2, 3], ('tupla', 'de', 'strings')]
print lista_de_cosas


[2, 5.5, 'letras', [1, 2, 3], ('tupla', 'de', 'strings')]

Para eliminar un elemento sólo tenemos que usar la función del e indicar la posición.


In [7]:
lista_de_cosas = [2, 5.5, 'letras', [1, 2, 3], ('tupla', 'de', 'strings')]
print 'Lista de cosas:', lista_de_cosas

del lista_de_cosas[3]
print 'Después de eliminar la posición 3:', lista_de_cosas


Lista de cosas: [2, 5.5, 'letras', [1, 2, 3], ('tupla', 'de', 'strings')]
Después de eliminar la posición 3: [2, 5.5, 'letras', ('tupla', 'de', 'strings')]

Y con las listas también se pueden hacer slices:


In [8]:
print 'primer elemento:', lista_de_cosas[0]
ultimo = lista_de_cosas[-1]
print 'último:', ultimo
print 'del_segundo_al_ultimo_sin_incluirlo:', lista_de_cosas[1:4]
print 'del_segundo_al_ultimo_sin_incluirlo:', lista_de_cosas[1:-1]
print 'del_segundo_al_ultimo_incluyendolo:', lista_de_cosas[1:]


primer elemento: 2
último: ('tupla', 'de', 'strings')
del_segundo_al_ultimo_sin_incluirlo: [5.5, 'letras', ('tupla', 'de', 'strings')]
del_segundo_al_ultimo_sin_incluirlo: [5.5, 'letras']
del_segundo_al_ultimo_incluyendolo: [5.5, 'letras', ('tupla', 'de', 'strings')]

Existe una función llamada range que crea permite crear listas de números:


In [9]:
print range.__doc__
print
print 'Ejemplos:'
print '  range(15):', range(15)
print '  range(15)[2:9]:', range(15)[2:9]
print '  range(15)[2:9:3]:', range(15)[2:9:3]
print '  range(2,9):', range(2,9)
print '  range(2,9,3):', range(2,9,3)


range(stop) -> list of integers
range(start, stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

Ejemplos:
  range(15): [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
  range(15)[2:9]: [2, 3, 4, 5, 6, 7, 8]
  range(15)[2:9:3]: [2, 5, 8]
  range(2,9): [2, 3, 4, 5, 6, 7, 8]
  range(2,9,3): [2, 5, 8]

Tuplas

Las tuplas son listas inmutables, es decir, que no se pueden modificar. Si no se pueden modificar, ¿para qué existen?. Porque crearlas es mucho más eficiente que crear listas y en muchas ocasiones, como con las constantes, queremos crear variables que no se modifiquen.


In [10]:
tupla = (1, 2, 3, 4)  # Se usa paréntesis en lugar de corchetes
print tupla

tupla = tupla[2:4]
print tupl
print type(tupla)


(1, 2, 3, 4)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-98180e13ced5> in <module>()
      3 
      4 tupla = tupla[2:4]
----> 5 print tupl
      6 print type(tupla)

NameError: name 'tupl' is not defined

Diccionarios

El equivalente a los registros de Pascal serían los diccionarios, pero éstos también ofrecen mayor flexibilidad:


In [ ]:
registros_con_campos_variables = {'campo1': 12, 'campo2': 'valor campo2'}
print registros_con_campos_variables
print type(registros_con_campos_variables)
print

print 'Le agrego un campo al diccionario'
registros_con_campos_variables['otro_campo'] = 432
print registros_con_campos_variables
print 

print 'Y ahora otro, pero con un int como índice'
registros_con_campos_variables[123] = 'también puede usarse los números como clave'
print registros_con_campos_variables

Además, se pueden usar los campos de un registro para armar una forma más simple los strings:


In [ ]:
alumno = {
    'nombre': 'Juan',
    'apellido': 'Perez',
    'nota': 2
}

print 'El alumno %(nombre)s %(apellido)s se sacó un %(nota)s' % alumno
print 'El alumno {nombre} {apellido} se sacó un {nota}'.format(**alumno)

Y si le queremos modificar la nota a un alumno, sólo tenemos que acceder a ese campo y asignarle un nuevo valor:


In [ ]:
alumno = {
    'nombre': 'Juan',
    'apellido': 'Perez',
    'nota': 2
}
print alumno

alumno['nota'] = 5
print alumno

O incluso se le puede cambiar el tipo de dato a un campo y agregar uno nuevo:


In [ ]:
alumno = {
    'nombre': 'Juan',
    'apellido': 'Perez',
    'parcial': 2
}
print 'Alumno:', alumno


alumno['parcial'] = [2, 6]  # Cambio el tipo de dato de int a list
print 'Agrego la nota del recuperatorio:', alumno

alumno['coloquio'] = 8  # Agrego un nuevo campo
print 'Agrego la nota del coloquio:', alumno

del alumno['parcial']  # Elimino el campo nota
print 'Elimino las notas del parcial:', alumno

Algo que hay que tener en cuenta es que el orden en que se asignan los campos a un registro no es el orden interno de esos campos.

Estructuras de control

Así como en Pascal se delimitan los bloques de código con las palabras reservadas begin y end, en Python se usan la indentación (espacios) para determinar qué se encuentra dentro de una estructura de control y qué no.

for

Si queremos imprimir los números del 0 al 14 podemos crear una lista con range y usar el for para imprimir cada valor:


In [ ]:
for i in range(15):
    print i

Incluso, si queremos imprimir los valores de una lista que nosotros armamos, también podemos hacerlo:


In [ ]:
for i in [1, 6, 3, 9, 5, 2]:
    print i

Y si queremos imprimir cada elemento de la lista junto con su posición podemos usar la función enumerate:


In [ ]:
lista = range(15, 30, 3)
print lista
for idx, value in enumerate(lista):
    print '%s: %s' % (idx, value)

También se puede usar la función zip para ir tomando los primeros elementos de una lista, después los segundos, y así sucesivamente


In [ ]:
for par in zip([1, 2, 3], [4, 5, 6]):
    print par

Y en realidad, se puede iterar sobre cualquier elemento iterable, como por ejemplo los strings:


In [ ]:
for caracter in "Hola mundo":
    print caracter

También se pueden iterar listas que tengan distintos tipos de elementos, pero hay que tener en cuenta qué se quiere hacer con ellos:


In [ ]:
lista = [1, 2, "12", "34", [5, 6]]
print 'La lista tiene los elementos:', lista
for elemento in lista:
    print '{0}*2: {1}:'.format(elemento, elemento*2)

while

El ciclo while también ejecuta un bloque de código mientras la condición sea verdadera:


In [ ]:
numero = 5
while numero < 10:
    print numero
    numero += 1

Las listas tienen una función llamada pop que lo que hace es tomar el último elemento de ella y lo elimina:


In [ ]:
lista = range(5)
print 'La lista antes de entrar al while tiene:', lista
while lista:  # Si la lista no esta vacía, sigo sacando elementos
    print lista.pop()

print 'La lista después de salir del while tiene:', lista

Aunque también podría obtener el primero:


In [ ]:
lista = range(5)
print 'La lista antes de entrar al while tiene:', lista
while lista:  # Si la lista no esta vacía, sigo sacando elementos
    print lista.pop(0)

print 'La lista después de salir del while tiene:', lista

Ejercicios

  1. Dado un número N, calcular su factorial
  2. Procesar una lista de números enteros, e imprimir para cada uno de ellos:
    • el número que se esta procesando
    • la suma parcial de los mismos
  3. La relación entre temperaturas Celsius y Fahrenheit está dada por: $$C = 5/9 * (F-32)$$ Escribir un algoritmo que haga una tabla de valores Celsius-Fahrenheit, para valores entre O F y 200 F , con intervalos de 10 grados.
  4. Procesar una lista de números enteros, e imprimir para cada uno de ellos:

    • el número que se esta procesando
    • la suma parcial de los mismos
    • True si el número era mayor al anterior y False en caso contrario

    Cortar cuando se los haya procesado a todos, o al alcanzar una suma parcial mayor o igual a 100

  5. Procesar una lista de números y generar un diccionario con dos claves llamadas "par" e "impar". Al terminar de procesar la lista el diccionario debe tener todos los números que proceso agrupados en pares e impares.

    Por ejemplo, si contamos con la lista [1, 5, 2, 6, 9, 3, 8], el diccionario que se obtenga debería ser: {"par": [2, 6, 8], "impar": [1, 5, 9, 3]}

  6. Dada una lista de números enteros y un entero k, escribir una función que muestre todo el vector multiplicado por k.
  7. Escribir una función que dadas dos listas de igual longitud imprima la suma de ellas posición a posición.
  8. Suponiendo que cuenta con una lista en la que en cada posición tiene la información de un alumno en un registro:
    [{'nombre': 'XX', 'padrón': 1, 'nota': 4, 'grupo': 1}, ...]
    
    1. Se desea imprimir el nombre y padrón de todos los alumnos aprobados.
    2. Asumiendo que la lista se encuentra ordenada por número de grupo, se pide indicar aquellos grupos para los cuales todos sus integrantes hayan aprobado el parcial recorriendo sólo una vez la lista.
  9. Se cuenta con dos listas de números ordenadas de forma creciente y se desea obtener una nueva lista ordenada que contenga todos los números, pero sin ordenarla nuevamente.
  10. Procesar una lista de strings e ir guardando en un diccionario la cantidad de ocurrencias de cada palabra (distinguir mayúsculas y minúsculas). Por ejemplo, para la lista
    ['Otra', 'posible', 'clasificacion', 'radica', 'en', 'si', 'una', 'variable', 'puede', 'cambiar', 'el', 'tipo', 'de', 'dato', 'que', 'se', 'puede', 'almacenar', 'en', 'ella', 'entre', 'una', 'sentencia', 'y', 'la', 'siguiente', '(', 'tipado', 'dinamico', ')', 'O', 'si', 'en', 'la', 'etapa', 'de', 'definicion', 'se', 'le', 'asigna', 'un', 'tipo', 'de', 'dato', 'a', 'una', 'variable', 'y', 'por', 'mas', 'que', 'se', 'puede', 'cambiar', 'el', 'contenido', 'de', 'la', 'misma', 'no', 'cambie', 'el', 'tipo', 'de', 'dato', 'de', 'lo', 'que', 'se', 'almacena', 'en', 'ella', '(', 'tipado', 'estatico', ')']
    
    El resultado sería:
    {'el': 3, 'en': 4, 'etapa': 1, 'por': 1, 'Otra': 1, 'contenido': 1, 'almacenar': 1, 'sentencia': 1, 'le': 1, 'tipo': 3, 'la': 3, ')': 2, '(': 2, 'almacena': 1, 'estatico': 1, 'dinamico': 1, 'mas': 1, 'cambiar': 2, 'tipado': 2, 'ella': 2, 'de': 6, 'definicion': 1, 'puede': 3, 'dato': 3, 'que': 3, 'O': 1, 'variable': 2, 'asigna': 1, 'entre': 1, 'a': 1, 'siguiente': 1, 'posible': 1, 'clasificacion': 1, 'no': 1, 'radica': 1, 'una': 3, 'si': 2, 'un': 1, 'misma': 1, 'lo': 1, 'y': 2, 'cambie': 1, 'se': 4}
    

In [ ]: