1.8. Todo sobre las listas

Las listas son el burro de carga en Python. Si si única experiencia con listas son los arrays de Visual Basic o (Dios lo prohiba) los datastore en Powerbuilder, prepárese para ver las listas de Python.

Nota
Una lista en Python es como un array en Perl. En Perl, las variables que almacenan arrays comienzan siempre con el carácter @; en Python, las variables pueden llamarse de cualquier modo, y Python lleva el registro del tipo de datos internamente.
Nota
Una lista en Python es muy parecida a un array en Java (aunque se puede usar de ese modo si eso es todo lo que se espera en la vida). Se puede comparar mejor con la clase Vector, que puede guardar objetos arbitrarios y expandirse dinámicamente al añadir nuevos elementos.

Ejemplo 1.14. Definición de una lista

>>> li = ["a", "b", "mpilgrim", "z", "example"] 1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0]                                       2
'a'
>>> li[4]                                       3
'example'
1 En primer lugar, definimos una lista de cinco elementos. Advierta que mantienen el orden original. Esto no es por azar. Una lista es un conjunto ordenado de elementos encerrados entre corchetes.
2 Una lista puede utilizarse como un array con primer índice 0. El primer elemento de una lista no vacía es siempre li[0].
3 El último elemento en esta lista de cinco es li[4], porque las listas siempre tienen como primer índice 0.

Ejemplo 1.15. Índices negativos en una lista

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[-1] 1
'example'
>>> li[-3] 2
'mpilgrim'
1 Un índice negativo da acceso a los elementos del final de la lista, contando hacia atrás. El último elemento de cualquier lista no vacía es siempre li[-1].
2 Si los índices negativos le resultan confusos, piénselo de este modo: li[n] == li[n - len(li)]. De modo que en esta lista, li[2] == li[2 - 5] == li[-3].

Ejemplo 1.16. Porciones de una lista

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:3]  1
['b', 'mpilgrim']
>>> li[1:-1] 2
['b', 'mpilgrim', 'z']
>>> li[0:3]  3
['a', 'b', 'mpilgrim']
1 Se puede obtener un subconjunto de una lista, llamado “porción”, especificando dos índices. El valor de retorno es una nueva lista que contiene todos los elementos de la lista original, en orden, empezando con el primer índice de la porción (en este caso li[1]), hasta el segundo índice de la porción (en este caso li[3]), pero sin incluir éste.
2 Las porciones funcionan si uno o ambos índices son negativos. Si le ayuda, el primer índice de la porción especifica el primer elemento que se desea obtener, y el segundo índice especifica el primer elemento que no se desea obtener. El valor de retorno es lo que hay entre medias.
3 Las listas comienzan en el índice 0, de manera que li[0:3] devuelve los tres primeros elementos de la lista, desde li[0] hasta li[3], sin incluir éste.

Ejemplo 1.17. Atajos para hacer porciones

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[:3] 1
['a', 'b', 'mpilgrim']
>>> li[3:] 2
['z', 'example']
>>> li[:]  3
['a', 'b', 'mpilgrim', 'z', 'example']
1 Si uno de los índices es 0, puede omitirse, y se sobreentiende. De modo que li[:3] es lo mismo que li[0:3] en el ejemplo anterior.
2 Advierta aquí la simetría. En esta lista de cinco elementos, li[:3] devuelve los tres primeros elementos, y li[3:] devuelve los dos últimos. De hecho, li[:n] devolverá siempre los n primeros elementos, y li[n:] devolverá el resto.
3 Si ambos índices se omiten, se incluirán todos los elementos de la lista. Pero esta lista no es la original; es una nueva lista que resulta tener los mismos elementos. li[:] es una forma abreviada para hacer una copia completa de una lista.

Ejemplo 1.18. Adición de elementos a una lista

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")               1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "new")            2
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"]) 3
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
1 append añade un elemento al final de la lista.
2 insert inserta un elemento en una lista. El argumento numérico es el índice del primer elemento que será desplazado de su posición. Advierta que los elementos de la lista no tienen que ser únicos; ahora hay dos elementos separados con el mismo valor, li[2] y li[6].
3 extend concatena listas. Advierta que no se llama a extend con varios argumentos; debe llamarse con un único argumento: una lista. En este caso, la lista tiene dos elementos.

Ejemplo 1.19. Búsqueda en una lista

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example") 1
5
>>> li.index("new")     2
2
>>> li.index("c")       3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
>>> "c" in li           4
0
1 index encuentra la primera aparición de un valor en la lista y devuelve su índice.
2 index encuentra la primera aparición de un valor en la lista. En este caso, new aparece dos veces en la lista, en li[2] y en li[6], pero index devuelve sólo el primer índice, 2.
3 Si el valor no se encuentra en la lista, Python lanza una excepción. Esto es notablemente distinto de la mayoría de los lenguajes, que devolverán un índice no válido. Aunque esto parezca molesto, es bueno, ya que significa que su programa terminará en el lugar donde se origina el problema, y no más adelante cuando se intente utilizar el índice no válido.
4 Para comprobar si un valor está en la lista, utilice in, que devuelve 1 si se encuentra el valor y 0 si no.
Nota
No hay un tipo booleano en Python. En un contexto booleano (como una sentencia if), 0 es falso y el resto de los números son verdaderos. Esto se extiende también a otros tipos de datos. Una cadena vacía (""), una lista vacía ([]) y un diccionario vacío ({}) son todos falsos; el resto de cadenas, listas y diccionarios son verdaderos.

Ejemplo 1.20. Eliminación de elementos de una lista

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.remove("z")   1
>>> li
['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("new") 2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("c")   3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> li.pop()         4
'elements'
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
1 remove elimina la primera aparición de un valor en una lista.
2 remove elimina sólo la primera aparición de un valor. En este caso, new aparece dos veces en la lista, pero li.remove("new") sólo elimina la primera.
3 Si el valor no se encuentra en la lista, Python lanza una excepción. Esto imita el comportamiento del método index.
4 pop es un animal curioso. Hace dos cosas: elimina el último elemento de la lista, y devuelve el valor que ha eliminado. Advierta que esto es diferente de li[-1], que devuelve el valor sin modificar la lista, y de li.remove(valor), que modifica la lista sin devolver ningún valor.

Ejemplo 1.21. Operadores de lista

>>> li = ['a', 'b', 'mpilgrim']
>>> li = li + ['example', 'new'] 1
>>> li
['a', 'b', 'mpilgrim', 'example', 'new']
>>> li += ['two']                2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = [1, 2] * 3              3
>>> li
[1, 2, 1, 2, 1, 2]
1 Las listas se pueden concatenar también con el operador +. lista = lista + otralista equivale a lista.extend(otralista) . Pero el operador + devuelve la nueva lista como valor, mientras que extend sólo modifica una lista existente.
2 Python admite el operador +=. li += ['two'] equivale a li = li + ['two']. El operador += funciona con listas, cadenas y enteros, y puede sobrecargarse para funcionar con clases definidas por el usuario. (Veremos más sobre clases en el capítulo 3).
3 El operador * funciona con listas como repetidor. li = [1, 2] * 3 equivale a li = [1, 2] + [1, 2] + [1, 2], que concatena las tres listas en una.

Lecturas complementarias