<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 ¿Qué es programar?
Un programa de ordenador es una serie de instrucciones que le dicen a la máquina qué tiene que hacer. Las máquinas no entienden nuestro lenguaje, por lo que tenemos que aprender un lenguaje para poder comunicarnos con ellas y darles órdenes. Hay muchísimos lenguajes de programación hoy en día, cada lenguaje se usa para hacer un tipo de programa. Por ejemplo, si quieres hacer una página web puedes usar HTML, CSS y Javascript, si quieres hacer un programa para consultar una base de datos puedes usar SQL. En el caso de Python, es un lenguaje usado para muchas cosas
Step1:  Ahora imagina que quieres hacer un programa para saludar a tu amiga Marta, ¿cómo lo harías? De primeras, podrías hacer lo siguiente
Step2:  Así, tendríamos un programa para saludar a cualquier Marta del mundo, pero, ¿y si quisiéramos un programa para poder saludar a cualquier persona? Para poder llevar esto a cabo necesitamos introducir un concepto de programación básico
Step3:  Operando con variables
En Python podemos hacer operaciones sobre las variables que tenemos de forma muy sencilla. A modo de resumen, las principales operaciones en python son
Step4:  También podemos multiplicar una palabra por un número usando el operador *.
Step5:  Y por último, también podemos hacer operaciones numéricas. En las operaciones numéricas Python respeta el orden de los operadores
Step6:  En el primer caso hemos realizado la operación 
$$5 + (6 * 2) = 5 + 12 = 17$$
y en el segundo, en cambio
$$ (5 + 6) * 2 = 11 * 2 = 22$$
Ejercicio
Step7:  Usando sólo la instrucción import debemos preceder la instrucción que queremos del nombre de la librería. Si este nombre es muy largo, podemos importar la librería usando un alias
Step8:  Ahora bien, si sólo vamos a usar unas operaciones concretas de una librería, podemos especificar cuáles son y así no tener que usar el nombre de la librería para poder utilizarlas.
Step9:  Esta librería tiene muchas más operaciones que puedes consultar en la documentación oficial
Estructuras de control
Hasta ahora, nuestros programas se basan en una serie de instrucciones que se ejecutan una detrás de otra. Esto limita mucho los programas que podemos hacer, ya que no nos permite controlar el flujo de ejecución (control flow) de nuestro programa. A continuación vamos a ver una serie de instrucciones especiales que nos permiten hacer precisamente eso.
if
Imagina que estás operando con raíces cuadradas, como sabrás la raíz cuadrada de un número es negativa, y quieres evitar hacer la raíz cuadrada si el número introducido por el usuario es negativo.
Step10:  ¿Qué podemos hacer para que no ocurra esto? Controlar con un if la condición de que el número sea positivo para hacer la raíz cuadrada y avisar al usuario en caso contrario
Step11:  Si quisiéramos controlar una condición más, usaríamos la instrucción elif, que en otros lenguajes como C es conocida como else if
Step12:  Ejercicio
Haz un programa que le pida al usuario un número (de ninjas). Si dicho número es menor que 50 y es par, el programa imprimirá "puedo con ellos!", en caso contrario imprimirá "no me vendría mal una ayudita..."
Nota
Step13:  Ejercicio
Haz un bucle while que imprima todos los números desde el 0 hasta un número que introduzca el usuario. Si el número que introduce es negativo puedes tomar dos decisiones
Step14:  ¿Qué es eso de la función range()? Sirve para generar una secuencia de números. Puedes consultar más sobre esta función en la documentación de Python. En Python 2, existían tanto range como xrange aunque en Python 3, range hace lo mismo que hacía xrange en Python 2.
Ejercicio
Genera con range los números pares del 0 al 10, ambos inclusive. ¿Qué cambiarías para generar del 2 al 10?
break
La sentencia break sirve para detener un bucle antes de que llegue al final (en un bucle for) o antes de que la condición sea falsa (en un bucle while). 
Los bucles (for y while) pueden tener una sentencia else como los if. Esta sentencia else se ejecuta si el bucle no ha terminado por un break y nos puede servir para controlar cuando un bucle termina o no debido a un break de forma sencilla.
El código siguiente refleja muy bien esto
Step15:  Cuando $n \% x = 0$, dejamos de hacer módulos con $n$ pues ya sabemos que no es primo. Por tanto, nos salimos del bucle con un break. Al salirnos con el break, no entramos en el else sino que volvemos al bucle inicial. En cambio, no hemos encontrado ningún $x$ tal que $n \% x = 0$, ejecutamos la condición else para decir que $n$ es primo.
Ejercicio
¿Cuál es la diferencia entre la sentencia break y la sentencia continue?
Pista
Step16:  Al imprimir la lista vemos los diferentes elementos que contiene. Pero, ¿y si queremos acceder a sólo uno de los elementos? En ese caso, necesitarás acceder mediante índices. Cada elemento de la lista tiene un número asociado con su posición dentro de la misma
Step17:  Si intentamos acceder a un índice superior al último de todos, 4, obtendremos un error
Step18:  Entonces, uno podría pensar que está obligado a conocer la longitud de la lista si quiere acceder al último elemento pero nada más lejos de la realidad! En python, también existen los índices inversos que nos permiten acceder a los elementos de la lista al revés
Step19:  Otra cosa que nos podemos hacer usando índices es quedarnos con una sublista. Por ejemplo, si quisiéramos quedarnos únicamente con un top 3 de amigos guays podríamos hacerlo usando el operador 
Step20:  Pero si queremos quedarnos con los tres primeros, podemos simplemente hacerlo de la siguiente forma
Step21:  ¿Y si queremos saber el resto? Simplemente, lo hacemos al revés!
Step22:  Ejercicio
Step23:  Ahora bien, en Python existe una forma mucho más cómoda de iterar sobre los valores de una lista sin tener que estar pendiente de un índice i
Step24:  En Python también existe lo que se llama list comprehesions, que son una forma mucho más sencilla y fácil de leer para crear listas. Por ejemplo, si queremos hacer una lista con las potencias de 2, podríamos hacerlo de la siguiente forma
Step25:  Tendríamos nuestra lista de potencias de 2 en tres líneas, pero con los list comprehesions podemos hacerlo en una única línea
Step26:  Ejercicio
Crea una lista con todos los números pares del 0 al 10 en una única línea.
Listas anidadas
Seguramente te habrás preguntado si se puede hacer una lista cuyos elementos sean listas, y la respuesta es ¡sí!. Esta representación de listas anidadas se suele usar para representar matrices. Por ejemplo, si queremos representar la siguiente matriz en Python
Step27:  Ejercicio
Crea la siguiente matriz en una línea
Step28:  Por tanto, para guardar en una lista tanto el nombre como la edad de nuestros amigos podríamos hacerlo de la siguiente forma
Step29:  Los valores de las tuplas también tienen índices, por tanto, en nuestro caso el nombre tendría el índice 0 y la edad el índice 1. Por tanto, si queremos acceder a la edad de Paloma tenemos que usar el operador [] dos veces
Step30:  Si queremos crear dos variables separadas para guardar el nombre y la edad de nuestro mejor amigo, podemos hacerlo en una sola línea!
Step31:  Cuidado! Si por casualidad un amigo cumpliese un año más no podríamos ponerlo en la tupla, debido a que las tuplas no pueden modificarse.
Step32:  Ejercicio
Step33:  Además, podemos hacer las operaciones típicas sobre conjuntos.
Step34:  Elementos de A que no están en B (diferencia)
Step35:  Elementos que están o bien en A o bien en B (unión)
Step36:  Elementos que están tanto en A como en B (intersección)
Step37:  Elementos que están en A o en B pero no en ambos (diferencia simétrica)
Step38:  ¿Podríamos hacer un conjunto de listas?
Step39:  ¡No! Esto es debido a que los elementos de los conjuntos deben ser hashables. Tal y como se explica en la documentación, un objeto es hashable si su clase define la función __hash__(), que calcula un entero para caracterizar a un objeto, por lo que objetos con el mismo valor deben tener el mismo entero hash, y la función __eq__(), que sirve para comparar objetos.
Las estructuras de datos que pueden cambiar su valor, como las listas o los diccionarios, no son hashables y, por lo tanto, no pueden ser elementos de un conjunto.
Iterando sobre conjuntos
Al igual que con las listas, también es posible iterar sobre conjuntos y hacer set comprehesions
Step40:  Ejercicio
¿Es buena idea usar la función set para eliminar los elementos repetidos de una lista? 
Un último detalle sobre conjuntos
Step41:  Para obtener la edad de Paloma, antes teníamos que estar mirando qué índice tenía en la lista, en cambio, ahora lo tenemos mucho más sencillo
Step42:  Si queremos saber los nombres de cada uno de nuestros amigos podemos listar las claves
Step43:  Y también podemos ver si hemos incluido a un amigo o no en nuestro diccionario
Step44:  La función dict nos permite hacer diccionarios directamente desde Tuplas de la siguiente forma
Step45:  Y cuando las keys son simples string también es posible definir un diccionario de la siguiente forma
Step46:  Iterando sobre diccionarios
Es posible crear diccionarios en una sola línea, usando las dict comprehesions. En el siguiente ejemplo, cada clave almacena su valor al cuadrado
Step47:  Aunque también es posible iterar sobre diccionarios usando bucles for. Para ello, usamos la función items
Step48:  Cuando iteramos sobre una lista o un conjunto, podemos usar la función enumerate para obtener la posición y el elemento de la misma forma
Step49:  Por último, si queremos iterar sobre dos listas o conjuntos a la vez (del mismo tamaño), podemos hacerlo usando la función zip
<ASSISTANT_TASK:>
Python Code:
print("Hola mundo!")
Explanation: ¿Qué es programar?
Un programa de ordenador es una serie de instrucciones que le dicen a la máquina qué tiene que hacer. Las máquinas no entienden nuestro lenguaje, por lo que tenemos que aprender un lenguaje para poder comunicarnos con ellas y darles órdenes. Hay muchísimos lenguajes de programación hoy en día, cada lenguaje se usa para hacer un tipo de programa. Por ejemplo, si quieres hacer una página web puedes usar HTML, CSS y Javascript, si quieres hacer un programa para consultar una base de datos puedes usar SQL. En el caso de Python, es un lenguaje usado para muchas cosas: desde hacer cálculos científicos hasta programación web, pasando por robótica, seguridad, ciencia de datos, física y muchísimas cosas más. Además, Python es muy sencillo de entender y programar, ya que simplifica muchas tareas que en otros lenguajes como C son muy tediosas. Por eso, es ideal para entender los conceptos básicos de programación y para iniciarse en este mundillo.
Instalación
Linux
Python viene instalado por defecto en todas las distribuciones Linux. En Ubuntu, la versión que viene instalada es python2 y en otras distribuciones como Arch Linux, la versión es python3. Lo recomendable si vas a iniciarte en Python es que empieces directamente por python3. Para comprobar la versión que tenemos instalada ejecutamos el siguiente comando en consola:
[marta@marta-PC ~]$ python -V
Python 3.6.0
En mi caso, tengo la versión 3.6 instalada. En el caso de que tengas una versión de python2, instala la versión 3 usando el siguiente comando:
Ubuntu: sudo apt-get install python3
CentOS: sudo yum install python3
Windows y Mac OS
Para instalar Python en otros sistemas operativos, descarga el instalador de la página oficial de python.
La consola de Python
Python es un lenguaje de programación interpretado, ¿qué quiere decir esto? que interpreta cada instrucción que hemos escrito en nuestro programa a la hora de ejecutar. Otros lenguajes, como C o Java son compilados, por lo que necesitamos generar un ejecutable (los famosos .exe, para que nos entendamos) para poder ejecutarlos. El hecho de que Python sea interpretado nos permite tener una consola donde introducir comandos sin tener que crear un programa y compilarlo. Podemos ejecutar esta consola simplemente ejecutando el siguiente comando:
```
[marta@marta-PC ~]$ python
Python 3.6.0 (default, Dec 24 2016, 08:03:08) 
[GCC 6.2.1 20160830] on linux
Type "help", "copyright", "credits" or "license" for more information.
```
También tenemos disponible la consola ipython, una consola de Python que resalta el código que escribimos y autocompleta si pulsamos el tabulador. Para ejecutarla simplemente tenemos que poner el siguiente comando en consola:
```
[marta@marta-PC ~]$ ipython
Python 3.6.0 (default, Dec 24 2016, 08:03:08) 
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
In [1]: 
```
Tanto el &gt;&gt;&gt; de la consola de Python como el In [1]: de la consola de iPython son conocidos como el prompt, donde podemos escribir instrucciones para que el intérprete las ejecute.
Jupyter
Un notebook de Jupyter es una especie de consola de Python que nos permite poder escribir comentarios en Markdown. Es muy útil para poder hacer tutoriales como éste, ya que dispones de la explicación y el código para ejecutar y probar en el mismo sitio. Vamos a empezar a usar la consola de python incluida en jupyter para hacer las primeras pruebas. Para instalar Jupyter podemos usar tanto pip como anaconda:
[marta@marta-PC ~]$ sudo pip3 install --upgrade pip &amp;&amp; sudo pip3 install jupyter
También puedes seguir las instrucciones de la página oficial de Jupyter 
```
Hola mundo!
Una vez tenemos Python instalado y hemos elegido nuestro intérprete favorito, vamos a empezar a programar. El primer programa que se suele hacer en todos los lenguajes de programación es conocido como el hola mundo. En otros lenguajes como C, tendríamos que hacer varias líneas de código y, después, compilar nuestro programa para poder ejecutarlo, en cambio, en Python lo podemos ejecutar en una sola línea!
End of explanation
print("Hola Marta!")
Explanation: Ahora imagina que quieres hacer un programa para saludar a tu amiga Marta, ¿cómo lo harías? De primeras, podrías hacer lo siguiente:
End of explanation
nombre = input("¿Cómo te llamas? ")
print("Hola ", nombre,"!")
Explanation: Así, tendríamos un programa para saludar a cualquier Marta del mundo, pero, ¿y si quisiéramos un programa para poder saludar a cualquier persona? Para poder llevar esto a cabo necesitamos introducir un concepto de programación básico: las variables.
Variables
Una variable en programación describe un lugar donde guardar información, que puede ser diferente en cada ejecución. En nuestro caso, queremos saludar al usuario que ejecute nuestro programa, pero no sabemos su nombre a priori y no lo sabremos hasta la ejecución, por tanto, necesitamos reservar un espacio para poder guardar ahí el nombre del usuario durante la ejecución de nuestro programa.
Hay muchos tipos de variables: 
números enteros (int)
números reales (float o double)
caracteres (char) y cadenas de caracteres (string)
booleanos (bool), estos últimos sólo pueden tomar dos valores: verdadero (True) o falso (False).
En otros lenguajes de programación, como C, necesitamos indicar el tipo que tiene cada variable que declaramos. En cambio, en python no es necesario ya que el propio intérprete lo infiere por sí mismo. 
Una vez hemos aprendido el concepto de variable, ya sí podemos hacer nuestro programa para saludar a cualquier persona.
End of explanation
nombre1 = "Marta"
nombre2 = "María"
suma_nombres = nombre1 + " y " + nombre2
print(suma_nombres)
Explanation: Operando con variables
En Python podemos hacer operaciones sobre las variables que tenemos de forma muy sencilla. A modo de resumen, las principales operaciones en python son:
| Símbolo | Operación     |
|:-------:|:-------------:|
|+        | suma          |
|-        | resta         |
|*        | multiplicación|
|/        | división      |
Estos operadores se pueden usar con cualquier tipo de variable, tanto números como letras. A continuación, te muestro varios ejemplos.
Podemos concatenar dos palabras usando el operador +.
End of explanation
num1 = 5
mult_letra_num = nombre1 * 5
print(mult_letra_num)
Explanation: También podemos multiplicar una palabra por un número usando el operador *.
End of explanation
num2 = 6
operacion1 = num1 + num2 * 2
print(operacion1)
operacion2 = (num1 + num2) * 2
print(operacion2)
Explanation: Y por último, también podemos hacer operaciones numéricas. En las operaciones numéricas Python respeta el orden de los operadores: primero se realizan las multiplicaciones y divisiones y, después, las sumas y restas. Si queremos cambiar este orden simplemente tenemos que usar paréntesis.
End of explanation
import math
print(math.sqrt(4))
Explanation: En el primer caso hemos realizado la operación 
$$5 + (6 * 2) = 5 + 12 = 17$$
y en el segundo, en cambio
$$ (5 + 6) * 2 = 11 * 2 = 22$$
Ejercicio:
Haz un pequeño programa que le pida al usuario introducir dos números ($x_1$ y $x_2$), calcule la siguiente operación y muestre el resultado de la misma ($x$):
$$ x = \frac{20 * x_1 - x_2}{x_2 + 3} $$
Si intentas operar con el resultado de la función input obtendrás un error que te informa que no se pueden restar dos datos de tipo str. Usa la función int para convertir los datos introducidos por teclado a datos numéricos.
Librería math
Una librería es un conjunto de operaciones relacionadas entre sí, guardadas en una especie de "paquete". En este caso, vamos a hablar de la librería math que tiene operaciones matemáticas más avanzadas tales como la raíz cuadrada.
Para poder usar esta librería debemos importarla a nuestro programa. Esto se hace usando la instrucción import:
End of explanation
import math as m
print(m.sqrt(4))
Explanation: Usando sólo la instrucción import debemos preceder la instrucción que queremos del nombre de la librería. Si este nombre es muy largo, podemos importar la librería usando un alias:
End of explanation
from math import sqrt
print(m.sqrt(4))
Explanation: Ahora bien, si sólo vamos a usar unas operaciones concretas de una librería, podemos especificar cuáles son y así no tener que usar el nombre de la librería para poder utilizarlas.
End of explanation
num = int(input("Introduce un número: "))
raiz = sqrt(num)
Explanation: Esta librería tiene muchas más operaciones que puedes consultar en la documentación oficial
Estructuras de control
Hasta ahora, nuestros programas se basan en una serie de instrucciones que se ejecutan una detrás de otra. Esto limita mucho los programas que podemos hacer, ya que no nos permite controlar el flujo de ejecución (control flow) de nuestro programa. A continuación vamos a ver una serie de instrucciones especiales que nos permiten hacer precisamente eso.
if
Imagina que estás operando con raíces cuadradas, como sabrás la raíz cuadrada de un número es negativa, y quieres evitar hacer la raíz cuadrada si el número introducido por el usuario es negativo.
End of explanation
num = int(input("Introduce un número: "))
if num > 0:
    raiz = sqrt(num)
else:
    print("No puedo hacer la raíz de un número negativo!")
Explanation: ¿Qué podemos hacer para que no ocurra esto? Controlar con un if la condición de que el número sea positivo para hacer la raíz cuadrada y avisar al usuario en caso contrario:
End of explanation
if num > 0:
    raiz = sqrt(num)
elif num == 0:
    print("Para qué quieres saber eso jaja saludos")
else:
    print("No puedo hacer la raíz de un número negativo!")
Explanation: Si quisiéramos controlar una condición más, usaríamos la instrucción elif, que en otros lenguajes como C es conocida como else if:
End of explanation
num = int(input("Introduce un número: "))
while (num < 0):
    num = int(input("Introduce un número: "))
raiz = sqrt(num)
print(raiz)
Explanation: Ejercicio
Haz un programa que le pida al usuario un número (de ninjas). Si dicho número es menor que 50 y es par, el programa imprimirá "puedo con ellos!", en caso contrario imprimirá "no me vendría mal una ayudita..."
Nota: para saber si un número es par o no debes usar el operador $\%$ y para saber si dos condiciones se cuplen a la vez, el operador lógico and
while
En el ejemplo anterior le decíamos al usuario que no podíamos hacer la raíz negativa de un número pero, ¿cómo haríamos para, en vez de darle este mensaje, volver a pedirle un número una y otra vez hasta que fuese negativo? Necesitamos ejecutar el mismo código hasta que se dé la condición que buscamos: que el usuario introduzca un número positivo.
Esto podemos hacerlo usando un bucle while!
End of explanation
for i in range(num):
    print(i)
Explanation: Ejercicio
Haz un bucle while que imprima todos los números desde el 0 hasta un número que introduzca el usuario. Si el número que introduce es negativo puedes tomar dos decisiones: pedirle que introduzca un número positivo o contar hacia atrás, tú eliges!
for
En lenguajes de programación como C o Java, un bucle for sirve para recorrer una secuencia de números, de la siguiente forma:
for (int i=0; i&lt;maximo_numero; i++)
Donde maximo_numero es una variable previamente definida. 
Hay también otro tipo de bucles for denominados forEach en Java que sirven para iterar sobre los elementos de cualquier estructura de datos (más adelante veremos lo que es). En Python, los bucles for tienen esta función: iterar sobre una serie de elementos. 
Para iterar sobre una serie de números, debemos generar dicha serie usando la función range(). Así, el ejercicio anteriormente pleanteado para resolverse con un bucle while sería:
End of explanation
for n in range(2,10):
    for x in range(2, n):
        if n % x == 0:
            print(n, " = ", x, " * ", n//x)
            break
    else:
        print(n, " es primo!")
Explanation: ¿Qué es eso de la función range()? Sirve para generar una secuencia de números. Puedes consultar más sobre esta función en la documentación de Python. En Python 2, existían tanto range como xrange aunque en Python 3, range hace lo mismo que hacía xrange en Python 2.
Ejercicio
Genera con range los números pares del 0 al 10, ambos inclusive. ¿Qué cambiarías para generar del 2 al 10?
break
La sentencia break sirve para detener un bucle antes de que llegue al final (en un bucle for) o antes de que la condición sea falsa (en un bucle while). 
Los bucles (for y while) pueden tener una sentencia else como los if. Esta sentencia else se ejecuta si el bucle no ha terminado por un break y nos puede servir para controlar cuando un bucle termina o no debido a un break de forma sencilla.
El código siguiente refleja muy bien esto: para saber si un número $n$ es primo calculamos su módulo entre todos los números en el intervalo $[2,n)$ y, en el momento en el que uno de estos módulos sea igual a $0$, sabremos que $n$ no es primo.
End of explanation
mis_amigos = ['Paloma', 'Paula', 'Teresa', 'Marina', 'Braulio']
print(mis_amigos)
Explanation: Cuando $n \% x = 0$, dejamos de hacer módulos con $n$ pues ya sabemos que no es primo. Por tanto, nos salimos del bucle con un break. Al salirnos con el break, no entramos en el else sino que volvemos al bucle inicial. En cambio, no hemos encontrado ningún $x$ tal que $n \% x = 0$, ejecutamos la condición else para decir que $n$ es primo.
Ejercicio
¿Cuál es la diferencia entre la sentencia break y la sentencia continue?
Pista: consúltalo en la documentación de Python.
Estructuras de datos
Por ahora sólo hemos estudiado variables en las que podemos guardar un único valor: un número, una letra, una frase... ¿No te da la impresión de que esto se queda algo corto? Sí, y probablemente no eres la única persona que lo ha pensado. Las estructuras de datos son variables compuestas, esto quiere decir que en ellas podemos almacenar muchos datos. Hay estructuras de datos de todo tipo, en python tenemos las siguientes:
Listas
Tuplas
Conjuntos
Diccionarios
Listas
Imagina que quieres guardar en una variable los nombres de tus mejores amigos. Una muy buena opción para hacerlo es una lista. Al igual que en la vida real hacemos listas como lista de cosas por hacer, lista para la compra, lista de propósitos de año nuevo, etc. en Python también podemos hacerlas usando esta estructura de datos.
Con las listas, podemos guardar en un mismo sitio variables relacionadas entre sí. Esto nos permite poder aplicar operaciones sobre todas ellas sin tener que repetir código. 
Para declarar una lista, usaremos los [].
End of explanation
mis_amigos[0]
Explanation: Al imprimir la lista vemos los diferentes elementos que contiene. Pero, ¿y si queremos acceder a sólo uno de los elementos? En ese caso, necesitarás acceder mediante índices. Cada elemento de la lista tiene un número asociado con su posición dentro de la misma:
| Elemento | Posición |
|:--------:|:--------:|
|Paloma    | 0        |
|Paula     | 1        |
|Teresa    | 2        |
|Marina    | 3        |
|Braulio   | 4        |
así, si por ejemplo queremos únicamente mostrar a nuestro mejor amigo, accederemos a él mediante el índice 0:
End of explanation
mis_amigos[5]
Explanation: Si intentamos acceder a un índice superior al último de todos, 4, obtendremos un error:
End of explanation
mis_amigos[-1]
Explanation: Entonces, uno podría pensar que está obligado a conocer la longitud de la lista si quiere acceder al último elemento pero nada más lejos de la realidad! En python, también existen los índices inversos que nos permiten acceder a los elementos de la lista al revés:
| Elemento | Posición |
|:--------:|:--------:|
|Paloma    | -5       |
|Paula     | -4       |
|Teresa    | -3       |
|Marina    | -2       |
|Braulio   | -1       |
Por lo que para acceder al último elemento de nuestra lista sólo tendríamos que usar el índice -1:
End of explanation
mis_amigos[0:3]
Explanation: Otra cosa que nos podemos hacer usando índices es quedarnos con una sublista. Por ejemplo, si quisiéramos quedarnos únicamente con un top 3 de amigos guays podríamos hacerlo usando el operador :
End of explanation
mis_amigos[:3]
Explanation: Pero si queremos quedarnos con los tres primeros, podemos simplemente hacerlo de la siguiente forma:
End of explanation
mis_amigos[3:]
Explanation: ¿Y si queremos saber el resto? Simplemente, lo hacemos al revés!
End of explanation
for i in range(len(mis_amigos)):
    print(mis_amigos[i])
Explanation: Ejercicio:
Haz una lista de la compra e imprime los siguientes elementos:
Penúltimo elemento
Del segundo al cuarto elemento
Los tres últimos
Todos!
Por último, elimina el tercer elemento de la lista usando la sentencia del
Iterando sobre una lista
Con los bucles podemos iterar sobre los valores de una lista. Típicamente, un programador C iteraría sobre una lista de la siguiente forma:
End of explanation
for amigo in mis_amigos:
    print(amigo)
Explanation: Ahora bien, en Python existe una forma mucho más cómoda de iterar sobre los valores de una lista sin tener que estar pendiente de un índice i:
End of explanation
potencias = []
for x in range(10):
    potencias.append(2**x)
print(potencias)
Explanation: En Python también existe lo que se llama list comprehesions, que son una forma mucho más sencilla y fácil de leer para crear listas. Por ejemplo, si queremos hacer una lista con las potencias de 2, podríamos hacerlo de la siguiente forma:
End of explanation
potencias = [x**2 for x in range(10)]
print(potencias)
Explanation: Tendríamos nuestra lista de potencias de 2 en tres líneas, pero con los list comprehesions podemos hacerlo en una única línea:
End of explanation
M = [[j for j in range(i, i+3)] for i in range(1,3)]
M
Explanation: Ejercicio
Crea una lista con todos los números pares del 0 al 10 en una única línea.
Listas anidadas
Seguramente te habrás preguntado si se puede hacer una lista cuyos elementos sean listas, y la respuesta es ¡sí!. Esta representación de listas anidadas se suele usar para representar matrices. Por ejemplo, si queremos representar la siguiente matriz en Python:
$$ M_{2 \times 3} = \left ( \begin{matrix}
1 & 2 & 3 \
2 & 3 & 4 
\end{matrix} \right)$$
Lo haríamos de la siguiente forma:
End of explanation
tupla_ejemplo = 5, 'perro', 3.6
print(tupla_ejemplo)
Explanation: Ejercicio
Crea la siguiente matriz en una línea:
$$ M_{2 \times 3} = \left ( \begin{matrix}
1 & 2 & 3 \
4 & 5 & 6 
\end{matrix} \right)$$
Tuplas
Imagina que deseas guardar tanto los nombres de tus mejores amigos como su edad. De primeras podrías pensar en hacer dos listas, de la siguiente forma:
| índice | 0 | 1 | 2 | 3 | 4 |
|:------:|:-:|:-:|:-:|:-:|:-:|
| nombres| Paloma | Paula | Teresa | Marina | Braulio |
| edades | 25 | 20 | 19 | 19 | 21 |
De tal forma que para saber la edad de Paloma (primer elemento de la lista nombres) tendríamos que mirar el primer elemento de la lista edades. Pero, ¿y si te dijera que en Python podríamos guardar en una misma variable la edad y el nombre de una persona? Se puede! Con las llamadas tuplas.
Una tupla es una serie de valores separados por comas.
End of explanation
amigos_edades = [('Paloma', 25), ('Paula', 20), ('Teresa', 19), ('Marina', 19), ('Braulio', 21)]
print(amigos_edades)
Explanation: Por tanto, para guardar en una lista tanto el nombre como la edad de nuestros amigos podríamos hacerlo de la siguiente forma:
End of explanation
amigos_edades[0][1]
Explanation: Los valores de las tuplas también tienen índices, por tanto, en nuestro caso el nombre tendría el índice 0 y la edad el índice 1. Por tanto, si queremos acceder a la edad de Paloma tenemos que usar el operador [] dos veces: una para acceder al elemento de la lista que queremos y otra para acceder al elemento de la tupla que queremos.
End of explanation
nombre, edad = amigos_edades[0]
print(nombre)
print(edad)
Explanation: Si queremos crear dos variables separadas para guardar el nombre y la edad de nuestro mejor amigo, podemos hacerlo en una sola línea!
End of explanation
amigos_edades[0][1] += 1
Explanation: Cuidado! Si por casualidad un amigo cumpliese un año más no podríamos ponerlo en la tupla, debido a que las tuplas no pueden modificarse.
End of explanation
mi_lista = [5,4,6,3,7,5,1,9,3]
print(mi_lista)
mi_conjunto = set(mi_lista)
print(mi_conjunto)
Explanation: Ejercicio:
Vuelve a hacer la lista de la compra que hiciste en el último ejercicio, pero esta vez guarda cada elemento de la lista de la compra junto con su precio. Después, imprime los siguientes elementos:
El precio del tercer elemento.
El nombre del último elemento.
Tanto el nombre como el precio del primer elemento.
Cojuntos
Un conjunto es una lista de elementos ordenados y en la que no hay elementos repetidos. Se definen con el operador {. Sus operadores básicos son eliminar elementos repetidos, consultar si un elemento está en el conjunto o no y, por supuesto, operaciones típicas de los conjuntos como la unión, la intersección, la diferencia...
¿Qué ventajas puede darte usar un conjunto en lugar de una lista? Al estar ordenados, es mucho más rápido encontrar un elemento aunque esto también hace que insertar nuevos elementos sea más costoso.
Podemos crear un conjunto a partir de una lista:
End of explanation
A = {1,2,4,5,6,7}
B = {2,3,5,6,8,9}
Explanation: Además, podemos hacer las operaciones típicas sobre conjuntos.
End of explanation
A - B
Explanation: Elementos de A que no están en B (diferencia):
End of explanation
A | B
Explanation: Elementos que están o bien en A o bien en B (unión):
End of explanation
A & B
Explanation: Elementos que están tanto en A como en B (intersección):
End of explanation
A ^ B
Explanation: Elementos que están en A o en B pero no en ambos (diferencia simétrica):
End of explanation
{[1,2,3],[4,5,6]}
Explanation: ¿Podríamos hacer un conjunto de listas?
End of explanation
{x for x in 'abracadabra' if x not in 'abc'}
for c in mi_conjunto:
    print(c)
Explanation: ¡No! Esto es debido a que los elementos de los conjuntos deben ser hashables. Tal y como se explica en la documentación, un objeto es hashable si su clase define la función __hash__(), que calcula un entero para caracterizar a un objeto, por lo que objetos con el mismo valor deben tener el mismo entero hash, y la función __eq__(), que sirve para comparar objetos.
Las estructuras de datos que pueden cambiar su valor, como las listas o los diccionarios, no son hashables y, por lo tanto, no pueden ser elementos de un conjunto.
Iterando sobre conjuntos
Al igual que con las listas, también es posible iterar sobre conjuntos y hacer set comprehesions:
End of explanation
mis_amigos = {'Paloma':25, 'Paula':20, 'Teresa':19, 'Marina':19, 
              'Braulio':21}
print(mis_amigos)
Explanation: Ejercicio
¿Es buena idea usar la función set para eliminar los elementos repetidos de una lista? 
Un último detalle sobre conjuntos: para crear un conjunto vacío usamos set() ya que usar {} creará un diccionario vacío.
Diccionarios
A diferencia de las estructuras de datos que hemos visto hasta ahora, los diccionarios no se indexan por números sino por claves (keys). Cada entrada de nuestro diccionario está formada por dos valores distintos: la clave y el valor. La clave nos sirve para acceder al elemento (valor) de forma rápida. Debido a que las claves sirven para identificar a cada elemento,deben ser únicas: si introduces un nuevo elemento en el diccionario con clave repetida, se sobreescribirá el elemento anterior así que ¡mucho cuidado!
Vamos a ver un pequeño ejemplo de uso de los diccionarios para que nos quede más claro. Volvamos al ejemplo anterior sobre nuestros amigos y su edad.
End of explanation
print(mis_amigos['Paloma'])
Explanation: Para obtener la edad de Paloma, antes teníamos que estar mirando qué índice tenía en la lista, en cambio, ahora lo tenemos mucho más sencillo:
End of explanation
list(mis_amigos.keys())
Explanation: Si queremos saber los nombres de cada uno de nuestros amigos podemos listar las claves:
End of explanation
'Marta' in mis_amigos
Explanation: Y también podemos ver si hemos incluido a un amigo o no en nuestro diccionario:
End of explanation
dict([('Paloma',25), ('Paula',20), ('Teresa',19), ('Marina', 19), 
      ('Braulio', 21)])
Explanation: La función dict nos permite hacer diccionarios directamente desde Tuplas de la siguiente forma:
End of explanation
dict(Paloma=25, Paula=20, Teresa=19, Marina=19, Braulio=21)
Explanation: Y cuando las keys son simples string también es posible definir un diccionario de la siguiente forma:
End of explanation
{x: x**2 for x in (2,4,6)}
Explanation: Iterando sobre diccionarios
Es posible crear diccionarios en una sola línea, usando las dict comprehesions. En el siguiente ejemplo, cada clave almacena su valor al cuadrado:
End of explanation
for nombre, edad in mis_amigos.items():
    print(nombre, edad)
Explanation: Aunque también es posible iterar sobre diccionarios usando bucles for. Para ello, usamos la función items:
End of explanation
for posicion, elemento in enumerate(['tic', 'tac', 'toe']):
    print(posicion, elemento)
Explanation: Cuando iteramos sobre una lista o un conjunto, podemos usar la función enumerate para obtener la posición y el elemento de la misma forma:
End of explanation
questions = ['name', 'quest', 'favourite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
    print("What is your {}? It is {}.".format(q,a))
Explanation: Por último, si queremos iterar sobre dos listas o conjuntos a la vez (del mismo tamaño), podemos hacerlo usando la función zip:
End of explanation
<END_TASK>