{ "metadata": { "name": "", "signature": "sha256:d40e408390d123aafe40af31e5e7d68dfd812d5f1fafb636c9588e5ef76425ef" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introducci\u00f3n a Python\n", "\n", "Vamos a hacer una peque\u00f1a introducci\u00f3n al lenguaje de programaci\u00f3n [Python](http://www.python.org). Para ello, me voy a apoyar principalmente en [el curso online de Python en CodeCademy](http://www.codecademy.com/es/tracks/python-latinamerica). Para profundizar y afianzar conceptos generales de Python es muy recomendable que hag\u00e1is por vuestra cuenta al menos los nueve primeros temas este curso.\n", "\n", "# Variables y tipos de datos\n", "\n", "En los lenguajes de programaci\u00f3n, una **variable** es un tipo de *identificador* que almacena o al que se le asigna un determinado valor. Este valor puede ser de distinto tipo, como veremos m\u00e1s adelante. Para asignar valores a variables, utilizamos el signo `=` con la siguiente sintaxis:\n", "\n", " nombre_de_variable = valor\n", "\n", "Veamos un ejemplo: vamos a *declarar* distintas variables, asign\u00e1ndoles valores:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# NOTA: en Python, las l\u00edneas que comienzan con # son comentarios\n", "# El int\u00e9rprete no las lee. Los humanos s\u00ed deber\u00edamos leerlas :-)\n", "mivariable = 25\n", "edad = 25\n", "year = 2013" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Una vez que hemos asignado valores a nombres de variables, podemos utilizar o recuperar esos valores siempre que lo necesitemos. \n", "\n", "Para hacer una peque\u00f1a prueba, vamos a imprimir por pantalla el valor de las variables anteriores. Para imprimir por pantalla, usamos la instrucci\u00f3n `print`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print mivariable\n", "print year\n", "print \"El ni\u00f1o come manzanas.\"\n", "print 255666" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "25\n", "2013\n", "El ni\u00f1o come manzanas.\n", "255666\n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "En el ejemplo anterior, hemos declarado tres variables diferentes. Sin embargo, el tipo de dato que est\u00e1bamos almacenando eras el mismo: n\u00fameros enteros. Como hemos mencionado antes, las variables pueden almacenar distintos tipos de datos. Los principales son: n\u00fameros enteros, n\u00fameros reales, cadenas de texto y valores *booleanos* (que nos permiten almacenar valores como verdadero o falso)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# n\u00fameros enteros (integer)\n", "hijos = 3\n", "\n", "# n\u00fameros reales (float), siempre indicando los decimales con punto\n", "precio = 350.25\n", "longitud = 1.5\n", "\n", "# cadenas de texto (string), siempre entre comillas simples o dobles\n", "nombre = \"Pedro\"\n", "apellidos = 'Sanz Hern\u00e1ndez'\n", "\n", "# valores booleanos (bool): solo pueden ser True o False, escritos tal cual sin comillas\n", "animal = True\n", "mineral = False" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "# imprimimos algunos de ellos por pantalla\n", "print hijos\n", "print nombre, apellidos\n", "print precio\n", "print mineral" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "3\n", "Pedro Sanz Hern\u00e1ndez\n", "350.25\n", "False\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los valores que contienen las variabes pueden ser reasignados en cualquier momento. Eso s\u00ed, solo almacenan el \u00faltimo valor que hayamos asignado. \n", "\n", "Si reasignamos algunas de las variables declaradas anteriormente e imprimimos sus valores por pantalla, comprobamos que \u00e9stos han cambiado:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nombre = \"Ana\"\n", "apellidos = 'Serrano de la Oca'\n", "print nombre, apellidos" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Ana Serrano de la Oca\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operaciones aritm\u00e9ticas\n", "\n", "Podemos utilizar el int\u00e9rprete de Python como una calculadora. Basta con introducir operaciones aritm\u00e9ticas como operadores que seguramente ya conoces: suma (`+`), resta (`-`), multiplicaci\u00f3n (`*`), divisi\u00f3n (`/`), potencias (`**`) y m\u00f3dulo (`%`). Vamos a imprimir por pantalla el resultado de algunas operaciones." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# en versiones anteriores a Python3, con esta l\u00ednea nos aseguramos que la divisi\u00f3n funciona como esperamos\n", "from __future__ import division\n", "\n", "#suma \n", "print 5+6\n", "\n", "# resta\n", "print 10-3\n", "\n", "# multiplicaci\u00f3n\n", "print 25*6\n", "\n", "# divisi\u00f3n\n", "print 2558/8\n", "\n", "# potencias\n", "print 2**3\n", "\n", "# m\u00f3dulo hace referencia al resto de la divisi\u00f3n 10/2.\n", "print 10%2" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "11\n", "7\n", "150\n", "319.75\n", "8\n", "0\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Si retomamos lo aprendido anteriormente acerca de las variables, veremos que podemos declarar variables a partir de operaciones matem\u00e1ticas, por ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# una suma sencilla\n", "suma = 9+5\n", "print suma" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "14\n" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "# calculamos el \u00e1rea de un cuadrado cuyo lado\n", "lado = 1.5\n", "area = lado**2 # es equivalente a lado*lado\n", "print area" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2.25\n" ] } ], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "# vamos a calcular el precio final de un producto cuyo valor es 19,95\u20ac\n", "iva = 21\n", "precio = 19.95\n", "precio_final = precio + (precio * iva)/100\n", "print precio_final" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "24.1395\n" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "# calculamos la edad actual de una persona\n", "ahora = 2014\n", "fechaNacimiento = 1985\n", "edad = ahora - fechaNacimiento\n", "print edad" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "29\n" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Gesti\u00f3n de cadenas (*strings*)\n", "\n", "Si nuestro objetivo es aprende a programar en Python para procesar texto, las **cadenas de caracteres** van a ser el principal tipo de dato que vamos a manejar. Como hemos visto antes, las cadenas se identifican en Python porque se declaran entre comillas dobles (`\"cadena\"`) o simples (`'cadena'`) o, si las cadenas son muy largas y ocupan m\u00e1s de una l\u00ednea, entre triples pares de comillas. \n", "\n", "Algunos ejemplos de cadenas:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "nombre = \"Godofredo de Orl\u00e9ans\"\n", "\n", "oracion = 'GREEN COLORLESS IDEAS SLEEP FURIOUSLY'\n", "\n", "parrafo = \"\"\"En un lugar de la Mancha, de cuyo nombre no quiero acordarme, \n", "no ha mucho tiempo que viv\u00eda un hidalgo de los de lanza en astillero, \n", "adarga antigua, roc\u00edn flaco y galgo corredor. Una olla de algo m\u00e1s vaca \n", "que carnero, salpic\u00f3n las m\u00e1s noches, duelos y quebrantos los s\u00e1bados, \n", "lentejas los viernes, alg\u00fan palomino de a\u00f1adidura los domingos, consum\u00edan \n", "las tres partes de su hacienda.\"\"\"" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "\u00a1OJO! Podemos definir como valores de variables cadenas formadas por secuencias de n\u00fameros, siempre que se declaren entre comillas. Es muy importante entender la diferencia entre:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "numero1 = 45852236\n", "numero2 = \"45852236\"\n", "\n", "# podemos realizar operaciones aritm\u00e9ticas entre n\u00fameros\n", "print numero1 + 1\n", "\n", "# pero no entre cadenas y n\u00fameros: esto da un error\n", "print numero2 + 1" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "45852237\n" ] }, { "ename": "TypeError", "evalue": "cannot concatenate 'str' and 'int' objects", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m# pero no entre cadenas y n\u00fameros: esto da un error\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[1;32mprint\u001b[0m \u001b[0mnumero2\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: cannot concatenate 'str' and 'int' objects" ] } ], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "# sin embargo, s\u00ed puedo utilizar el operador '+' para concatenar varias cadenas\n", "print numero2 + \"1\"\n", "print \"\u00a1Hola\" + \" \" + \"amigo!\"" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "458522361\n", "\u00a1Hola amigo!\n" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Conversi\u00f3n ente cadenas y enteros\n", "\n", "Otra manera de generar cadenas de texto es utilizando la funci\u00f3n `str()` con un argumento que no sea una cadena. F\u00edjate en los ejemplos:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# guardamos en numero1 un entero\n", "numero1 = 45852236\n", "# en numero2, guardamos el valor de numero1 convertido a cadena de texto con la funci\u00f3n str()\n", "numero2 = str(numero1)\n", "\n", "# con la funci\u00f3n type() imprimimos por pantalla el tipo de dato que guarda una variable\n", "\n", "print type(numero1) # es un entero: int\n", "print type(numero2) # es una cadena: str" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "\n" ] } ], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para hacer el paso contrario, es decir, transformar cadenas en enteros, podemos utilizar la funci\u00f3n `int()`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# guardamos en numero1 una cadena\n", "numero1 = \"45852236\"\n", "# en numero2, guardamos el valor de numero1 convertido a entero con la funci\u00f3n int()\n", "numero2 = int(numero1)\n", "\n", "# con la funci\u00f3n type() imprimimos por pantalla el tipo de dato que guarda una variable\n", "\n", "print type(numero1) # es una cadena: str\n", "print type(numero2) # es un entero: int" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "\n" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Recuerda, cualquier secuencia alfanum\u00e9rica encerrada entre comillas ser\u00e1 tratada como una cadena de caracteres (*string*) aunque est\u00e9 formada \u00fanicamente por d\u00edgitos.\n", "\n", "\n", "### M\u00e9todos sobre cadenas\n", "\n", "Existe una serie de *funciones* y *metodos* que podemos ejecutar sobre cadenas de texto y que nos van a permitir realizar operaciones y transformar dichas cadenas de distintas maneras, p. ej.: \n", "\n", "- contar el n\u00famero de caracteres de una cadena (`len()`) \n", "- transformar la cadena a may\u00fasculas (`.upper()`) o min\u00fasculas (`.lower()`)\n", "\n", "Para m\u00e1s info, consulta [los m\u00e9todos que podemos aplicar a las cadenas](http://rgruet.free.fr/PQR27/PQR2.7.html#stringMethods).\n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print len(nombre) # devuelve la longitud (en n\u00famero de caracteres) de una cadena\n", "print oracion.lower() # transforma una cadena a min\u00fasculas (lowercas)\n", "print parrafo.upper() # transforma una cadena a may\u00fasculas (uppercas)\n", "print \"AbCdEfGhIjKlMn\u00d1oPqRsTuVwXyZ\".swapcase() # transforma may\u00fasculas a min\u00fasculas y viceversa" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "21\n", "green colorless ideas sleep furiously\n", "EN UN LUGAR DE LA MANCHA, DE CUYO NOMBRE NO QUIERO ACORDARME, \n", "NO HA MUCHO TIEMPO QUE VIV\u00edA UN HIDALGO DE LOS DE LANZA EN ASTILLERO, \n", "ADARGA ANTIGUA, ROC\u00edN FLACO Y GALGO CORREDOR. UNA OLLA DE ALGO M\u00e1S VACA \n", "QUE CARNERO, SALPIC\u00f3N LAS M\u00e1S NOCHES, DUELOS Y QUEBRANTOS LOS S\u00e1BADOS, \n", "LENTEJAS LOS VIERNES, ALG\u00faN PALOMINO DE A\u00f1ADIDURA LOS DOMINGOS, CONSUM\u00edAN \n", "LAS TRES PARTES DE SU HACIENDA.\n", "aBcDeFgHiJkLmN\u00d1OpQrStUvWxYz\n" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Listas\n", "\n", "Las **listas** de Python son una estructura de datos que almacenan una colecci\u00f3n de diferentes tipos de informaci\u00f3n en forma de secuencia ordenada, bajo un solo nombre de variable. Las listas pueden guardar valores de cualquiera de los tipos que hemos visto anteriormente (cadenas, n\u00fameros y booleanos) e incluso **las listas pueden incluir otras listas de manera anidada**.\n", "\n", "Las listas se declaran especificando la colecci\u00f3n de elementos entre corchetes y separando los elementos con comas:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "dias = [\"lunes\", \"martes\", \"mi\u00e9rcoles\", \"jueves\", \"viernes\", \"s\u00e1bado\", \"domingo\"]\n", "misCosas = [23.4, True, oracion.lower()]\n", "listaVacia = []\n", "\n", "# los imprimimos por pantalla\n", "print numeros\n", "print dias\n", "print misCosas\n", "print listaVacia" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", "['lunes', 'martes', 'mi\\xc3\\xa9rcoles', 'jueves', 'viernes', 's\\xc3\\xa1bado', 'domingo']\n", "[23.4, True, 'green colorless ideas sleep furiously']\n", "[]\n" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las listas son estructuras de datos ordenadas, lo que implica que podemos acceder a los elementos individuales a trav\u00e9s de un \u00edndice (la posici\u00f3n que ocupa en la secuencia). El \u00edndice se especifica indicando el nombre de la lista y un entero entre corchetes: `nombre_de_lista[\u00edndice]`.\n", "\n", "\u00a1OJO! Los \u00edndices de las listas comienzan con 0, no con 1: el primer elemento es `nombre_de_lista[0]`. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "print \"el primer d\u00eda de la semana es \" + dias[0]\n", "print \"el tercer d\u00eda de la semana es \" + dias[2]\n", "print \"y el \u00faltimo es \" + dias[-1]\n", "\n", "# podemos utilizar los \u00edndices tambi\u00e9n para reasignar valores a los elementos de una lista\n", "# p. ej., cambiamos el primer valor de la lista misCosas\n", "misCosas[0] = 44\n", "print misCosas\n", "\n", "# \u00a1OJO! si intentamos acceder a un \u00edndice que no existe, el int\u00e9rprete nos dar\u00e1 error\n", "print misCosas[8]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "el primer d\u00eda de la semana es lunes\n", "el tercer d\u00eda de la semana es mi\u00e9rcoles\n", "y el \u00faltimo es domingo\n", "[44, True, 'green colorless ideas sleep furiously']\n" ] }, { "ename": "IndexError", "evalue": "list index out of range", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[1;31m# \u00a1OJO! si intentamos acceder a un \u00edndice que no existe, el int\u00e9rprete nos dar\u00e1 error\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[1;32mprint\u001b[0m \u001b[0mmisCosas\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m8\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mIndexError\u001b[0m: list index out of range" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos acceder a *porciones de una lista* usando una notaci\u00f3n especial en los corchetes del \u00edndice. `nombre_de_lista[n:m]` devuelve la secuencia de elementos de la lista que va desde el \u00edndice *n* hasta el *m*." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# imprime los tres primeros elementos de la variable dias\n", "print dias[:3]\n", "# imprime elementos del 3\u00ba al 6\u00aa de la variable n\u00fameros\n", "print numeros[2:6]\n", "# imprime los tres \u00faltimos n\u00fameros de la variable n\u00fameros\n", "print numeros[-3:]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['lunes', 'martes', 'mi\\xc3\\xa9rcoles']\n", "[3, 4, 5, 6]\n", "[8, 9, 10]\n" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Las cadenas, al igual que las listas, son estructuras ordenadas. No lo hemos mencionado antes, pero podemos utilizar esta misma notaci\u00f3n de \u00edndices para acceder a elementos y a porciones de una cadena." ] }, { "cell_type": "code", "collapsed": false, "input": [ "cadena = \"perrogatorana\"\n", "print cadena[:5]\n", "print cadena[5:9]\n", "print cadena[-4:]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "perro\n", "gato\n", "rana\n" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## M\u00e9todos sobre listas\n", "\n", "Como con las cadenas, en las listas existen una serie de *funciones* y *m\u00e9todos* que podemos ejecutar y que nos van a permitir realizar operaciones y transformar dichas listas de distintas maneras, p. ej.:\n", "\n", "- podemos contar el n\u00famero de elementos de una lista con la funci\u00f3n `len()`.\n", "- podemos buscar elementos en una lista sin saber la posici\u00f3n concreta que ocupan con el m\u00e9todo `.index()`. \n", "- podemos a\u00f1adir nuevos elementos al final de una lista con el m\u00e9todo `.append()`.\n", "- podemos a\u00f1adir nuevos elementos en una posici\u00f3n concreta de una lista con el m\u00e9todo `.insert()`.\n", "- podemos eliminar elementos de una lista con los m\u00e9todos `.remove()` y `.pop()`.\n", "- podemos concatenar una lista con otra con el m\u00e9todo `.extend()`.\n", "\n", "Para m\u00e1s info, consulta los [m\u00e9todos que podemos aplicar a las listas](http://rgruet.free.fr/PQR27/PQR2.7.html#list)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# creamos una lista vac\u00eda\n", "miLista = []\n", "# \u00bfest\u00e1 realmente vac\u00eda?\n", "print len(miLista)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n" ] } ], "prompt_number": 21 }, { "cell_type": "code", "collapsed": false, "input": [ "# \u00bfqu\u00e9 posici\u00f3n ocupa \"jueves\" en la lista dias\n", "print dias.index(\"jueves\")" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "3\n" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "# a\u00f1adimos varios elementos nuevos y vemos c\u00f3mo va aumentando la lista\n", "miLista.append(2)\n", "print miLista\n", "miLista.append(\"palabra\")\n", "print miLista\n", "miLista.append(25**3)\n", "print miLista" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2]\n", "[2, 'palabra']\n", "[2, 'palabra', 15625]\n" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [ "# a\u00f1adimos como cuarto elemento otra lista de elementos: f\u00edjate en la estructura del resultado\n", "miLista.append(numeros)\n", "print miLista" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2, 'palabra', 15625, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]\n" ] } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "# \u00bfcu\u00e1ntos elementos tiene miLista?\n", "print \"la lista miLista tiene \" + str(len(miLista)) + \" elementos\"" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "la lista miLista tiene 4 elementos\n" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": [ "# a\u00f1adimos como segundo elemento otro nuevo valor\n", "miLista.insert(1, \"segundo elemento\")\n", "print miLista" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2, 'segundo elemento', 'palabra', 15625, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]\n" ] } ], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": [ "print miLista\n", "\n", "# eliminarmos el elemento 2 y el elemento \"palabra\" de miLista\n", "miLista.remove(2)\n", "print miLista" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2, 'segundo elemento', 'palabra', 15625, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]\n", "['segundo elemento', 'palabra', 15625, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]\n" ] } ], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": [ "miLista.remove(\"palabra\")\n", "print miLista" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['segundo elemento', 15625, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]\n" ] } ], "prompt_number": 28 }, { "cell_type": "code", "collapsed": false, "input": [ "# tambi\u00e9n puedo eliminar el \u00faltimo elemento de la lista\n", "miLista.pop(-1)\n", "print miLista" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['segundo elemento', 15625]\n" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "# concateno dos listas\n", "dias.extend(numeros)\n", "print dias" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['lunes', 'martes', 'mi\\xc3\\xa9rcoles', 'jueves', 'viernes', 's\\xc3\\xa1bado', 'domingo', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n" ] } ], "prompt_number": 30 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Tuplas\n", "\n", "Las **tuplas** de Python son una estructura de datos que almacenan una colecci\u00f3n de diferentes tipos de informaci\u00f3n en forma de secuencia ordenada. Estas tuplas pueden guardar valores de cualquiera de los tipos que hemos visto anteriormente (cadenas, n\u00fameros y booleanos) e incluso otras listas o tuplas de manera anidada. La principal diferencia con las listas es que **las tuplas son inmutables**: no podemos modificarlas, ni a\u00f1adiendo o eliminando elementos, ni reordenado, etc. \n", "\n", "Las tuplas se declaran especificando la colecci\u00f3n de elementos entre par\u00e9ntesis y separando los elementos con comas." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# creo tres tripletas, cada una almacenando el nombre, apellido y sexo de unas personas ficticias\n", "tripleta1 = (\"Carlos\", \"Pujol\", \"H\")\n", "tripleta2 = (\"Montse\", \"Santos\", \"M\")\n", "tripleta3 = (\"Ana\", \"Ruiz\", \"M\")\n", "\n", "# creo una lista de personas y a\u00f1ado las tripletas por orden\n", "personas = []\n", "personas.append(tripleta1)\n", "personas.append(tripleta2)\n", "personas.append(tripleta3)\n", "print personas\n", "\n", "# las tuplas son secuencias ordenadas, y como tales podemos acceder a sus elementos\n", "# a trav\u00e9s de \u00edndices num\u00e9ricos\n", "print len(personas[0])\n", "print personas[1][1]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[('Carlos', 'Pujol', 'H'), ('Montse', 'Santos', 'M'), ('Ana', 'Ruiz', 'M')]\n", "3\n", "Santos\n" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Diccionarios\n", "\n", "Los **diccionarios** de Python son una estructura de datos que almacena una colecci\u00f3n de pares *clave:valor*. La clave es siempre una cadena, y el valor puede contener cualquiera de los tipos que hemos visto anteriormente (cadenas, n\u00fameros y booleanos) e incluso otras listas, tuplas o diccionarios de manera anidada. Al contrario que las listas y las tuplas, los diccionarios no son estructuras ordenadas. Por lo tanto, nos interesar\u00e1 utilizar diccionarios cuando necesitamos almacenar y acceder directamente a informaci\u00f3n cuyo nombre conozcamos.\n", "\n", "Podemos definir diccionarios de varias maneras:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# entre llaves, separando claves y valores con dos puntos, y separando pares con comas\n", "victor = {\"nombre\": \"Victor\", \"apellido\": \"Peinado\", \"sexo\": \"H\", \"edad\": 36}\n", "print victor\n", "\n", "# declarando el diccionario como una estructura vac\u00eda y a\u00f1adiendo los pares clave:valor despu\u00e9s\n", "antonio = {}\n", "antonio[\"nombre\"] = \"Antonio\"\n", "antonio[\"apellido\"] = \"Santos\"\n", "antonio[\"sexo\"] = \"H\"\n", "antonio[\"edad\"] = 26\n", "print antonio\n", "\n", "# creo una lista de diccionarios: OJO, la lista s\u00ed est\u00e1 ordenada\n", "personas = [victor, antonio]\n", "print personas" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'edad': 36, 'nombre': 'Victor', 'apellido': 'Peinado', 'sexo': 'H'}\n", "{'edad': 26, 'nombre': 'Antonio', 'apellido': 'Santos', 'sexo': 'H'}\n", "[{'edad': 36, 'nombre': 'Victor', 'apellido': 'Peinado', 'sexo': 'H'}, {'edad': 26, 'nombre': 'Antonio', 'apellido': 'Santos', 'sexo': 'H'}]\n" ] } ], "prompt_number": 32 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos acceder a los elementos del diccionaro a trav\u00e9s del nombre de la clave:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print victor[\"nombre\"]\n", "\n", "print antonio[\"apellido\"]\n", "\n", "print personas[1][\"nombre\"]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Victor\n", "Santos\n", "Antonio\n" ] } ], "prompt_number": 33 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## M\u00e9todos sobre diccionarios\n", "\n", "Como con otras estructuras de datos, los diccionarios proporcionan una serie de *funciones* y *m\u00e9todos* que podemos ejecutar y que nos van a permitir manipular y acceder a dichos diccionarios de distintas maneras, p. ej.:\n", "\n", "- podemos contar el n\u00famero de elementos de una diccionario la funci\u00f3n `len()`.\n", "- podemos recuperar una lista conteniendo las claves de un diccionario con el m\u00e9todo `.keys()`.\n", "- podemos recuperar una lista conteniendo los valores de un diccionario con el m\u00e9todo `.values()`.\n", "- podemos comprobar que un diccionario contiene determinada clave con el m\u00e9todo `.has_key()`.\n", "- podemos eliminar un elemento de un diccionario con el m\u00e9todo `.pop()`.\n", "\n", "Para m\u00e1s info, consulta los [m\u00e9todos que podemos aplicar a los diccionarios](http://rgruet.free.fr/PQR27/PQR2.7.html#dictionary)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# \u00bfcu\u00e1ntos pares clave:valor tiene el diccionario antonio?\n", "print len(antonio)\n", "\n", "# dame las claves\n", "print antonio.keys()\n", "\n", "# dame los valores\n", "print antonio.values()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "4\n", "['edad', 'nombre', 'apellido', 'sexo']\n", "[26, 'Antonio', 'Santos', 'H']\n" ] } ], "prompt_number": 34 }, { "cell_type": "code", "collapsed": false, "input": [ "# recuerda que para crear nuevos pares clave:valor, basta con asignarles un valor\n", "antonio[\"altura\"] = 1.79\n", "\n", "# podemos comprobar si el diccionario tiene determinadas claves\n", "print antonio.has_key(\"email\")\n", "print antonio.has_key(\"altura\")\n", "print antonio" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "False\n", "True\n", "{'edad': 26, 'nombre': 'Antonio', 'altura': 1.79, 'apellido': 'Santos', 'sexo': 'H'}\n" ] } ], "prompt_number": 35 }, { "cell_type": "code", "collapsed": false, "input": [ "# eliminamos la clave altura de antonio\n", "antonio.pop(\"altura\") \n", "print antonio" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'edad': 26, 'nombre': 'Antonio', 'apellido': 'Santos', 'sexo': 'H'}\n" ] } ], "prompt_number": 36 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los diccionarios pueden contener otros diccionarios anidados, lo que conlleva que podemos manejar estructuras bastante complejas. A modo de ejemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# creo un diccionario de la familia Pig, en principio vac\u00edo\n", "familiaPig = {}\n", "\n", "# creo varios diccionarios por cada miembro de la familia\n", "hija = {\"nombre\": \"Peppa\", \"apellido\": \"Pig\", \"email\": \"peppa@pig.com\",}\n", "hijo = {\"nombre\": \"George\", \"apellido\": \"Pig\", \"email\": \"george@pig.com\",}\n", "padre = {\"nombre\": \"Daddy\", \"apellido\": \"Pig\", \"email\": \"daddy@pig.com\",}\n", "madre = {\"nombre\": \"Mommy\", \"apellido\": \"Pig\", \"email\": \"mommy@pig.com\",}\n", "\n", "\n", "familiaPig[\"hija\"] = hija\n", "familiaPig[\"hijo\"] = hijo\n", "familiaPig[\"padre\"] = padre\n", "familiaPig[\"madre\"] = madre\n", "\n", "print familiaPig" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'hijo': {'nombre': 'George', 'email': 'george@pig.com', 'apellido': 'Pig'}, 'madre': {'nombre': 'Mommy', 'email': 'mommy@pig.com', 'apellido': 'Pig'}, 'padre': {'nombre': 'Daddy', 'email': 'daddy@pig.com', 'apellido': 'Pig'}, 'hija': {'nombre': 'Peppa', 'email': 'peppa@pig.com', 'apellido': 'Pig'}}\n" ] } ], "prompt_number": 37 }, { "cell_type": "code", "collapsed": false, "input": [ "# \u00bfCu\u00e1l es el email de la madre?\n", "print familiaPig[\"madre\"][\"email\"]\n", "\n", "# \u00bfY el nombre de la hija?\n", "print familiaPig[\"hija\"][\"nombre\"]\n", "\n", "# en lugar de un diccionario, puedo crear tambi\u00e9n una lista con los miembros de la familia ordenados por edad\n", "familia = [padre, madre, hija, hijo]\n", "\n", "# ahora solo puedo acceder por \u00edndices, as\u00ed que \u00bfcu\u00e1l es el email del primer miembro de la familia?\n", "print familia[0][\"email\"]\n", "\n", "# \u00bfY el nombre del miembro m\u00e1s joven?\n", "print familia[-1][\"nombre\"]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "mommy@pig.com\n", "Peppa\n", "daddy@pig.com\n", "George\n" ] } ], "prompt_number": 38 }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.core.display import Image\n", "Image(\"http://peppapigjuegos.com/img/wallpapers/2pag/peppa_pig_family.jpg\")" ], "language": "python", "metadata": {}, "outputs": [ { "jpeg": "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABBAAD/4QMraHR0cDov\nL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENl\naGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4\nOnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6\nMzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5\nOS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHht\nbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0i\naHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1w\nPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlk\nOjI4QzdFMUNGMkVCNjExRTM4ODlBOTdBMUZBQzgwM0QwIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAu\naWlkOjI4QzdFMUNFMkVCNjExRTM4ODlBOTdBMUZBQzgwM0QwIiB4bXA6Q3JlYXRvclRvb2w9IkFk\nb2JlIFBob3Rvc2hvcCBDUzUgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmlu\nc3RhbmNlSUQ9InhtcC5paWQ6MjQ4RkUyQTUxQUM2MTFFMjlDMzBDQ0ZBMTFBM0ZDRTMiIHN0UmVm\nOmRvY3VtZW50SUQ9InhtcC5kaWQ6MjQ4RkUyQTYxQUM2MTFFMjlDMzBDQ0ZBMTFBM0ZDRTMiLz4g\nPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9\nInIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAFBAQEBAQFBAQFBwUEBQcJBwUFBwkKCAgJCAgKDQoL\n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\n9h89+IOoy6b1K7jwfCrV53IaNXMVfNSWqhHz9tK4u4wzOJJqMmJx3gLobfU8RrRcic38/auNvi0v\nyE2zQvNGSMcegEFS43rc9TT8pfG9B6mvOZFlMhP6X4/crdpXYci4kuJJqScSV5hck29LqclWpFYy\nhv8ARLOz1KCfT5Mrb974pLZ5NHOjBpIxpOFcuI6VmtRU018X0qjqug4WPm2p47or7lFwe1pe/FV0\nVppW/wAh1Ov6HaQWj7y0hgsXWdMj6taJ48uLTh364NrvW5VLOxKJ6X1XpONjWHO3GFiNvbWnEqbe\n2uhV0s5mKVkzBJGasKlJ1OXjJNVWomql4QBAEAQBAEKGkvLkTyUZ+VHs6z0rU5+R8COW67np/gw8\nvqKy1pzJ13JVhDLdTajOS1loBwwDT4nVFcOpTunWqzc9x6d+nPSo3b0sl6Xa9mPfJOr82jy9h3r7\nVt1dWeoMurmMWzJmeWY9otZhNw6OlYWlxdFwzw6OA+I1W3o+I9YlCauVro3E4bCxtPOvtLdlt565\nlvbzJmo+5mOaSQ5i7Fx3DDqSKpqKWbSt6EcNzPrNh5SXSbJofK5449w0k912amY497duWszMmFOG\nJ55468T2J48sO2+ZcnTipqhRp07ZaEnTy6dBy+nGz800X9BbOFHkhxI+XKRj6cFrYUrpPL+mPH51\nL/8ACevXXyU29+jfUs3OoMgkltNHa2GBxfELkYzyM2FxeRVlQNjKBUuXaaI/tPUf0/wbeZ1V8iKj\niY2ly1zuaaW6yelcTXFwx4VRUZWaMlMuFNlNyjI+hnpLAv74N4YuZcvRxHU+1Z/mbv3n5zDyLda0\nXmMOaQP4ge5sm3OCQ6vTXasXG612mThXDTYXLTVoZHka5Ay9EYOSagbNxGD4aublzA9D6rPau19/\nSfOXjK1Z6d1e5by7Su2Li5tp0pJVr7PEqcSUqqkuLRQ1M72vmkkb3XOOT4Wx4bvhZ8I9SM8syJqV\nxtaq7kvQtC8hn09hkuWg78HfiNPetT1mX/LNfeaXpO2/TfF53W7b/pRnPzRovS0ditSfSAQBAEAQ\nBAEByt9bul1AW8Lc0sr8sY2Vc99AMVtOitu3KG6b9f2ngP6mYUpdZtqC9q9at+WVXH7EUbiGS2mk\ngnaWTRktew95rgtw1TQzzfIsTsXHbmuGUXRowqlDATZJJH+W5zfQSFnhk3YapSXlZfCbWp0M3nbr\n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\nCUASgCUASgCUB7Q5fX0hVpoB/9k=\n", "metadata": {}, "output_type": "pyout", "prompt_number": 39, "text": [ "" ] } ], "prompt_number": 39 } ], "metadata": {} } ] }