Programar Juegos Arcade
con Python y PygameChapter 7: Introducción a las Listas
7.1 Tipos de Datos
Hasta el momento, en este libro hemos mostrado cuatro tipos de datos:
- Cadena (una cadena es una abreviatura para “cadena de caracteres,” lo que la gente habitualmente entiende por texto.)
- Entero
- Real (Coma flotante)
- Booleano
Python puede mostrar la clase a la que pertenece cada valor mediante la función type.
No obstante, debemos admitir que esta función type no es muy útil para el resto de lo que haremos en este libro, pero es bueno que al menos por una vez, mostremos los tipos de datos que hemos introducido hasta ahora. Escribe lo siguiente en la shell del IDLE. (No vayas a abrir una ventana nueva y escribirlo como un programa; no funcionaría).
type(3) type(3.145) type("¡Qué tal!") type(True) |
Salida:
>>> type(3) <class 'int'> >>> type(3.145) <class 'float'> >>> type("Qué tal") <class 'str'> >>> type(True) <class 'bool'> |
También es posible usar la función type en una variable para ver qué clase de dato hay en ella.
x = 3 type(x)
Los dos nuevos tipos de datos que veremos en este capítulo son las Listas y las Tuplas. Intenta ejecutar los siguientes comandos sobre la shell de Python y observa el resultado:
type((2, 3, 4, 5)) type([2, 3, 4, 5])
7.2 Trabajando Con Listas
Seguramente has creado listas de la compra, listas de lo que queda por hacer y hasta quizás, listas de lo que tienes que hacer antes de morir. ¿Pero cómo creas listas en un ordenador?
Intenta estos ejercicios usando la línea de comandos del IDLE. Haz lo siguiente para crear una lista e imprimirla:
>>> x = [1,2] >>> print(x) [1, 2]
Para imprimir un elemento (item) individual de un array:
>>> print(x[0]) 1
Este número con la ubicación del item se llama el índice. Observa que las posiciones en la lista empiezan por cero. Por ello, una lista con 10 items, no tiene un item en la ubicación [10]. Solo ubica desde [0] hasta [9]. Puede parecer muy confuso crear un array con 10 items y que no haya un elemento 10, pero la mayoría de lenguajes de ordenador empiezan a contar desde el 0 en lugar de hacerlo desde el 1.
Piensa en una lista como en una cubitera de hielo que guarda números, como la que se ve en la Figura 7.2. Los valores son guardados dentro de cada cubículo y lo que está escrito arriba son los números que empezando por cero identifican la ubicación de cada sitio.
Recuerda, tenemos que considerar dos conjuntos de números cuando trabajamos con listas de números: la posición y el valor. La posición, también conocida como índice, se refiere a dónde se encuentra el valor. El valor es el número guardado en esa ubicación. Cuando trabajamos con un array, debemos tener claro si lo que necesitamos es su ubicación o su valor.
Es fácil obtener el valor conociendo la ubicación, pero es mucho más difícil obtener la ubicación conociendo el valor. El Capítulo 16 lo dedicaremos a responder cómo encontrar la ubicación para un determinado valor.
Un programa puede asignar nuevos valores a items individuales en una lista. En el caso siguiente, al primero, ubicado en la posición cero (no uno), se le asigna el número 22.
>>> x[0] = 22 >>> print(x) [22, 2]
Un programa también puede crear una “tupla”. Este tipo de datos trabaja como una lista, pero con dos diferencias. Primero, la creamos con paréntesis en lugar de corchetes. Segundo, no es posible cambiar el valor de una tupla una vez creada:
>>> x = (1, 2) >>> print(x) (1, 2) >>> print(x[0]) 1 >>> x[0] = 22 Traceback (most recent call last): File "<pyshell#18>", line 1, in <module> x[0] = 22 TypeError: 'tuple' object does not support item assignment >>>
Como se puede ver en el código anterior, no podemos asignar un valor nuevo a un item de la tupla. ¿Pero por qué necesitamos esta limitación? Primero, el ordenador irá más rápido si sabe que un valor no cambiará. Segundo, no queremos que ciertas listas cambien, como por ejemplo una lista con los colores RGB para el rojo. El color rojo no cambia, por lo tanto una tupla inmutable es la mejor opción.
Un array es una lista de objetos. Es una estructura de datos muy importante en informática. El tipo de dato “lista” de Python es muy similar a una estructura de datos del tipo array (colección).
7.3 Iterando En Una Lista
Si un programa necesita iterar a través de cada item de una lista, como por ejemplo, para imprimirlos, existen dos tipos de bucles for que pueden hacerlo.
El primer método para iterar a través de cada item en un bucle, es usando el bucle “para-cada”. Este tipo de bucle toma una colección de items, iterando el código una vez por item. Hará una copia del item y lo almacenará en una variable para su procesamiento.
Tiene el siguiente formato:
for variable_item in nombre_lista:
Estos son algunos ejemplos:
mi_lista = [101, 20, 10, 50, 60] for item in mi_lista: print(item) |
Salida:
101 20 10 50 60 |
Los Programas también pueden almacenar cadenas de caracteres en listas:
mi_lista = ["Cuchara", "Tenedor", "Cuchillo"] for item in mi_lista: print(item) |
Salida:
Cuchara Tenedor Cuchillo |
Las listas también pueden contener otras listas. Lo siguiente itera a través de cada item de la lista principal, pero no en las sublistas.
mi_lista = [[2, 3], [4, 3], [6, 7]] for item in mi_lista: print(item) |
Salida:
[2,3] [4,3] [6,7] |
La otra forma de iterar a través de una lista es usar una variable índice que acceda directamente a la lista, en lugar de hacerlo a través de una copia de cada elemento. Para usar una variable índice, el programa cuenta desde 0 hasta la longitud de la lista. Si hay diez elementos, el bucle debe ir desde 0 hasta 9 para el total de los diez elementos.
La longitud de una lista la podemos hallar usando la función len. Combinándola con la función range, permite que el bucle itere a través de la lista completa.
mi_lista = [101, 20, 10, 50, 60] for i in range(len(mi_lista)): print(mi_lista[i]) |
Salida:
101 20 10 50 60 |
Este método es más complejo, pero también más potente. Como estamos trabajando directamente con los elementos de la lista, en lugar de hacerlo con una copia, podemos modificarla. El bucle para-cada no permite modificaciones de la lista original.
7.4 Añadir a una Lista
Podemos añadir nuevos items a una lista (pero no a una tupla) usando el comando append. Por ejemplo:
mi_lista = [2, 4, 5, 6] print(mi_lista) mi_lista.append(9) print(mi_lista) |
Salida:
[2, 4, 5, 6] [2, 4, 5, 6, 9] |
Nota: Si el rendimiento se ve alterado por la función “append”, es muy importante comprender cómo se implementa una lista. Por ejemplo, si la lista se implementa como una colección (array) de datos, añadir un item a la lista se parece mucho a añadir otro huevo a un cartón lleno. Por lo que un cartón nuevo debe ser fabricado con trece depósitos. Los doce huevos son retirados y, luego, añadimos el decimotercer huevo. Finalmente, el viejo cartón es reciclado. Ya que esto sucede entre bastidores de una función, los programadores podrían olvidarlo y dejar que el ordenador hiciera todo el trabajo. Sería mucho más eficiente, decirle simplemente que fabricara un cartón con los depósitos necesarios para comenzar. Por suerte, Python no implementa las listas como colecciones de datos. Pero, es importante prestar atención en el próximo semestre, a la clase sobre estructura de datos y aprender cómo funciona todo esto.
Para crear una lista desde cero, es necesario crear primero una lista vacía y luego usar la función append. El siguiente ejemplo crea una lista basada en las entradas de teclado:
mi_lista = [] # Lista vacía for i in range(5): entrada_usuario = input("Introducir un número entero: ") entrada_usuario = int(entrada_usuario) mi_lista.append(entrada_usuario) print(mi_lista) |
Salida:
Introducir un número entero: 4 [4] Introducir un número entero: 5 [4, 5] Introducir un número entero: 3 [4, 5, 3] Introducir un número entero: 1 [4, 5, 3, 1] Introducir un número entero: 8 [4, 5, 3, 1, 8] |
Si un programa necesitara crear un array de una longitud específica, con todos sus elementos del mismo valor, un sencillo truco sería usar el siguiente código:
# Crear un array con 100 ceros. mi_lista = [0] * 100
7.5 Sumar o Modificar una Lista
Crear un total acumulado de un array es una operación rutinaria. Así es como se haría:
# Copia de un array a una suma mi_lista = [5, 76, 8, 5, 3, 3, 56, 5, 23] # La suma inicial debería ser cero total_lista = 0 # Itera desde 0 hasta el total del número de elementos # en el array: for i in range(len(mi_lista)): # Añade el elemento 0, después el 1, luego el 2, etc. total_lista += mi_lista[i] # Imprime el resultado print(total_lista)
En lugar de contar a través de un rango, podemos conseguir lo mismo usando un bucle for que itere a través del array:
# Copia de un array a una suma mi_lista = [5, 76, 8, 5, 3, 3, 56, 5, 23] # La suma inicial debería ser cero total_lista = 0 # Itera a través del array, copiando cada item del mismo en una # variable llamada item. for item in mi_lista: # Añade cada item total_lista += item # Imprime el resultado print(total_lista)
Los números en un array también pueden cambiarse usando un bucle for:
# Copia del array a modificar mi_lista = [5, 76, 8, 5, 3, 3, 56, 5, 23] # Itera desde 0 hasta el total del número de elementos # en el array: for i in range(len(mi_lista)): # Modifica el elemento duplicándolo mi_lista[i] = mi_lista[i] * 2 # Imprime el resultado print(mi_lista)
Sin embargo, la versión siguiente no funciona a la hora de duplicar los valores del array. ¿Por qué? Debido a que item es una copia de un elemento del array. El código siguiente duplica la copia, pero no el elemento original del array.
# Copia del array a modificar mi_lista = [5, 76, 8, 5, 3, 3, 56, 5, 23] # Itera a través de cada elemento en mi_lista for item in mi_lista: # Esto duplica el item, pero no modifica el array, # debido a que item es una copia de un único elemento. item = item * 2 # Imprime el resultado print(mi_lista)
7.6 Dividir Cadenas de Texto
Las cadenas de texto son en realidad listas de caracteres. Pueden tratarse como listas donde cada letra es un item particular. Ejecuta el código siguiente con las dos versiones de x:
x = "Esta es una cadena de ejemplo" #x = "0123456789" print("x=", x) # Acceso a un carácter individual print("x[0] = ", x[0]) print("x[1] = ", x[1]) # Acceso desde la derecha print("x[-1] = ", x[-1]) # Acceso 0 - 5 print("x[:6] = ", x[:6]) # Acceso 6 print("x[6:] = ", x[6:]) # Acceso 6 - 8 print("x[6:9] = ", x[6:9])
En Python podemos aplicar ciertos operadores matemáticos a las cadenas de texto. Intenta reproducir el siguiente código:
a = "Hola" b = "Qué tal" c = "!" print(a + b) print(a + b + c) print(3 * a) print(a * 3) print((a * 2) + (b * 2))
Ya hemos visto que es posible conocer la longitud de una cadena. También es posible saberlo con cualquier otro tipo de array.
a = "Hola, qué tal" print(len(a)) b = [3, 4, 5, 6, 76, 4, 3, 3] print(len(b))
Como una cadena de texto es un array, un programa también podría iterar a través de cada uno de sus elementos:
for caracter in "Esto es una prueba": print (caracter)
Ejercicio: Empieza con el siguiente código:
meses = "EneFebMarAbrMayJunJulAgoSepOctNovDic" n = int(input("Introduce un número de mes: "))
Imprime la abreviatura (de tres letras) para el número de mes que introduzca el usuario. (Calcula la posición inicial en la cadena, luego, usa la información que hemos aprendido para imprimir la subcadena correcta)
7.7 Códigos Secretos
Este código imprime individualmente cada letra de una cadena de texto:
texto_llano = "Esto es una prueba. ABC abc" for c in texto_llano: print (c, end=" ")
Los ordenadores realmente no almacenan letras de una cadena en su memoria; almacenan series de números. Cada número representa una letra. El sistema que usan para traducir números a letras se llama Unicode. El nombre completo es Universal Character Set Transformation Format, abreviado habitualmente como UTF-8.
La tabla Unicode cubre el alfabeto Occidental usando los números 0-127. Cada letra es representada por un byte de memoria. Otros alfabetos, como el Cirílico, pueden emplear múltiples bytes para representar cada letra. Una copia parcial de la tabla Unicode se puede ver debajo:
Valor | Carácter | Valor | Carácter | Valor | Carácter | Valor | Carácter |
40 | ( | 61 | = | 82 | R | 103 | g |
41 | ) | 62 | > | 83 | S | 104 | h |
42 | * | 63 | ? | 84 | T | 105 | i |
43 | + | 64 | @ | 85 | U | 106 | j |
44 | , | 65 | A | 86 | V | 107 | k |
45 | - | 66 | B | 87 | W | 108 | l |
46 | . | 67 | C | 88 | X | 109 | m |
47 | / | 68 | D | 89 | Y | 110 | n |
48 | 0 | 69 | E | 90 | Z | 111 | o |
49 | 1 | 70 | F | 91 | [ | 112 | p |
50 | 2 | 71 | G | 92 | \ | 113 | q |
51 | 3 | 72 | H | 93 | ] | 114 | r |
52 | 4 | 73 | I | 94 | ^ | 115 | s |
53 | 5 | 74 | J | 95 | _ | 116 | t |
54 | 6 | 75 | K | 96 | ` | 117 | u |
55 | 7 | 76 | L | 97 | a | 118 | v |
56 | 8 | 77 | M | 98 | b | 119 | w |
57 | 9 | 78 | N | 99 | c | 120 | x |
58 | : | 79 | O | 100 | d | 121 | y |
59 | ; | 80 | P | 101 | e | 122 | z |
60 | < | 81 | Q | 102 | f |
Para una mayor información sobre ASCII (el cual posee los mismos valores que Unicode para el alfabeto Occidental) ir a:
http://es.wikipedia.org/wiki/ASCII
Vídeo que explica la elegancia del Unicode:
http://hackaday.com/2013/09/27/utf-8-the-most-elegant-hack
El siguiente conjunto de líneas convierte cada letra del ejemplo anterior en su valor ordinal usando UTF-8:
texto_llano = "Esto es una prueba. ABC abc" for c in texto_llano: print (ord(c), end=" ")
El siguiente programa toma cada valor UTF-8 y le añade un uno. Luego, imprime el nuevo valor UTF-8, y por último, lo vuelve a convertir a una letra
texto_llano = "Esto es una prueba. ABC abc" for c in texto_llano: x = ord(c) x = x + 1 c2 = chr(x) print (c2, end="")
El siguiente programa toma cada valor UTF-8 y le añade un uno. Luego, lo vuelve a convertir a una letra.
""" # Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # Vídeo explicativo: http://youtu.be/sxFIxD8Gd3A """ texto_plano = "Esto es una prueba. ABC abc" texto_cifrado = "" for c in texto_plano: x = ord(c) x = x + 1 c2 = chr(x) texto_cifrado = texto_cifrado + c2 print(texto_cifrado)
Finalmente, el último código, toma cada valor UTF-8 y le sustrae un uno, luego lo convierte en una letra. Usando la salida del programa anterior como entrada de éste, podemos emplearlo como descifrador del texto cifrado en el anterior ejemplo.
""" # Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # Vídeo explicativo: http://youtu.be/sxFIxD8Gd3A """ texto_cifrado = "Ftup!ft!vob!qsvfcb/!BCD!bcd" texto_plano= "" for c in texto_cifrado: x = ord(c) x = x - 1 c2 = chr(x) texto_plano = texto_plano + c2 print(texto_plano)
7.8 Arrays Asociativos
Python no se limita a usar números como índices de arrays. También es posible usar un array asociativo. Un array asociativo funciona de la siguiente manera:
# Crea un array asociativo vacío # (Observar las llaves.) x = {} # Añadirle algo x["fred"] = 2 x["scooby"] = 8 x["wilma"] = 1 # Obtener e imprimir un item print(x["fred"])
Realmente no necesitas arrays asociativos para este capítulo, pero creo que es importante señalar que es posible usarlos.
7.9 Repaso
7.9.1 Test
7.9.2 Ejercicios
Haz click para ir a los Ejercicios.
7.9.3 Taller
You are not logged in. Log in here and track your progress.
English version by Paul Vincent Craven
Spanish version by Antonio Rodríguez Verdugo
Russian version by Vladimir Slav
Turkish version by Güray Yildirim
Portuguese version by Armando Marques Sobrinho and Tati Carvalho
Dutch version by Frank Waegeman
Hungarian version by Nagy Attila
Finnish version by Jouko Järvenpää
French version by Franco Rossi
Korean version by Kim Zeung-Il
Chinese version by Kai Lin