Control de flujo e Iterables

Por simplificar muchísimo tenemos fundamentalmente condicionales y bucles.

Condicionales

Con los condicionales (if-else, if-elif-else) podemos ejecutar o no una parte del código dependiendo de si se cumple una condición que evalúa a un booleano (True o False).

# Creemos una variable para experimentar
una_variable = 5

# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python!
# imprime "una_variable es menor que 10"
if una_variable > 10:
    print("una_variable es mayor que 10.")
elif una_variable < 10: # Esta condición 'elif' es opcional.
    print("una_variable es menor que 10")
else: # También es opcional.
    print("una_variable es de hecho 10.")

Bucles

Con los bucles (for, while) podemos repetir una sección del código un número concreto de veces (for) o mientras se cumpla una condición que evalúe a True(while).

For

Itera sobre iterables como lo son las colecciones (listas, tuplas, cadenas, diccionarios) o los generadores. Sabemos con antelación el número de repeticiones en las que vamos a iterar.

"""
imprime:
    perro es un mamifero
    gato es un mamifero
    raton es un mamifero
"""
for animal in ["perro", "gato", "raton"]:
    print("{} es un mamifero".format(animal))

"""
`range(número)` retorna un generador de números
desde cero hasta el número dado
imprime:
    0
    1
    2
    3
"""
for i in range(4): # range es una función de python que retorna una lista de elementos
    print(i)

While

Itera mientras se cumpla una condición, o hasta que la condición deje de cumplirse.

"""
imprime:
    0
    1
    2
    3
"""
x = 0
while x < 4:
    print(x)
    x += 1  # equivalente a x = x + 1

Manejo de excepciones

En cualquier software que hagamos podrían aparecer errores. Esos errores "rompen" el flujo habitual de nuestro programa, lanzan Excepciones, las cuales tendremos que gestionar con los bloques try-except. Para levantar una excepción, hacemos uso de la palabra reservada raise. Veamos un ejemplo.

# Maneja excepciones con un bloque try/except
try:
    # Usa raise para levantar un error
    raise IndexError("Este es un error de indice")
except IndexError as e:
    pass    # Pass no hace nada. Usualmente harias alguna recuperacion aqui.

Iterables

Python oferce una abstracción fundamental llamada Iterable. Un iterable es un objeto que puede ser tratado como una sequencia. El objeto es retornado por la función 'range' es un iterable.

dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
nuestro_iterable = dicc_lleno.keys()
print(nuestro_iterable) #=> dict_keys(['uno', 'dos', 'tres']). Este es un objeto que implementa nuestra interfaz Iterable

# Podemos recorrerla.
for i in nuestro_iterable:
    print(i)    # Imprime uno, dos, tres

# Aunque no podemos selecionar un elemento por su índice.
nuestro_iterable[1]  # Genera un TypeError

# Un iterable es un objeto que sabe como crear un iterador.
nuestro_iterator = iter(nuestro_iterable)

# Nuestro iterador es un objeto que puede recordar el estado mientras lo recorremos.
# Obtenemos el siguiente objeto llamando la función __next__.
nuestro_iterator.__next__()  #=> "uno"

# Mantiene el estado mientras llamamos __next__.
nuestro_iterator.__next__()  #=> "dos"
nuestro_iterator.__next__()  #=> "tres"

# Después que el iterador ha retornado todos sus datos, da una excepción StopIterator.
nuestro_iterator.__next__() # Genera StopIteration

# Puedes obtener todos los elementos de un iterador llamando a list() en el.
list(dicc_lleno.keys())  #=> Retorna ["uno", "dos", "tres"]